Tỷ lệ thiết bị Lego


23

Tôi đang chế tạo một robot lego khổng lồ và tôi cần tạo ra một số tỷ số truyền cụ thể bằng cách sử dụng một bộ bánh răng. Tôi có rất nhiều bánh răng với các kích thước bánh răng lego phổ biến: 8, 16, 24 hoặc 40 răng. Viết chương trình Tôi có thể sử dụng khi tôi nhập tỷ số truyền và chương trình cho tôi biết tôi nên sử dụng tổ hợp bánh răng nào để có tỷ lệ được yêu cầu.

Tỷ lệ đầu vào sẽ được chỉ định trên đầu vào tiêu chuẩn (hoặc tương đương với ngôn ngữ của bạn) với hai số nguyên được phân tách bằng dấu hai chấm. Một tỷ lệ a:bcó nghĩa là trục đầu ra sẽ quay a/bnhanh như trục đầu vào.

Sản lượng đầu ra tiêu chuẩn phải là một dòng duy nhất chứa một danh sách không gian tách biệt của tỷ số truyền động, theo hình thức x:ynơi xlà kích thước của các bánh răng trên trục đầu vào và ylà kích thước của các bánh răng trên trục đầu ra. Bạn phải sử dụng số lượng bánh răng tối thiểu có thể cho tỷ lệ nhất định. Mỗi xyphải là một trong 8,16,24,40.

ví dụ:

1:5 -> 8:40
10:1 -> 40:8 16:8
9:4 -> 24:16 24:16
7:1 -> IMPOSSIBLE
7:7 ->
6:15 -> 16:40

Nếu tỷ lệ bánh răng mong muốn là không thể, hãy in "TÁC ĐỘNG". Nếu không có bánh răng được yêu cầu, in chuỗi trống.

Đây là mã golf, câu trả lời ngắn nhất thắng.


Không phải tỷ lệ của răng tỷ lệ nghịch với vận tốc góc? Vì vậy, ví dụ nếu tốc độ đầu ra đầu vào mong muốn là 1: 5, thì tỷ lệ này có phải là 40: 8 thay vì 8:40 không? Hoặc là tỷ lệ tay trái là răng bánh răng hiệu quả so với tỷ lệ răng bánh răng thực tế bạn muốn?
DavidC

Câu hỏi thú vị ... 1:5 -> 8:4010:1 -> 40:8có ý nghĩa nhưng những người khác không quá nhiều.
Cướp

@DavidCarraher: Tôi đoán bạn có thể định nghĩa nó theo một trong hai cách. Tôi đã cố gắng để được nhất quán trong nội bộ. 1:5có nghĩa là trục đầu ra quay chậm hơn 5 lần và một bánh răng 8 ở đầu vào và một bánh răng 40 ở đầu ra làm cho điều đó xảy ra.
Keith Randall

@MikeDtrick: tốt 10:1 -> 40:8 16:8, không phải những gì bạn nói. Những gì về những người khác làm bạn bối rối? 9:4được thực hiện làm 3:2hai lần. 3:2được thực hiện bằng cách sử dụng 24:16.
Keith Randall

2
@MikeDtrick: Có cho câu hỏi đầu tiên của bạn. Để có được 10: 1 bạn có thể thực hiện 5: 1 (sử dụng 40 răng / 8 răng) và sau đó 2: 1 (sử dụng 16 răng / 8 răng). 7:7là giống như 1:1, vì vậy nó không đòi hỏi phải có bánh răng để thực hiện.
Keith Randall

Câu trả lời:


4

Con trăn - 204

Ok, tôi sẽ đi trước:

def p(n,a=[1]*9):
 n=int(n)
 for i in(2,3,5):
    while n%i<1:n/=i;a=[i]+a
 return a,n
(x,i),(y,j)=map(p,raw_input().split(':'))
print[' '.join(`a*8`+':'+`b*8`for a,b in zip(x,y)if a!=b),'IMPOSSIBLE'][i!=j]
chỉnh sửa:

Để 'tối ưu hóa' đầu ra, điều này có thể được thêm vào trước printcâu lệnh,

for e in x:
 if e in y:x.remove(e);y.remove(e)

Tôi tin rằng tổng số lên tới 266 ký tự .


1
<1Có thể thay thế ==0. Ngoài ra, if b:a=...return acó thể được return b and...or a.
ugoren

Không làm việc cho, ví dụ , 23:12.
Keith Randall

Cũng phát hiện ra. Nó đi qua kể từ 12 là chia được. Thêm elif i!=1:return[]vào bản gốc giải quyết vấn đề nhưng giới thiệu một vấn đề khác. $ python gears.py <<< 21:28=> 24:16.. Tôi sẽ xem xét nó. Dường như vấn đề không đơn giản như vậy: DI Hãy nghĩ rằng mã phải dài hơn nữa, hoặc tôi cần một cách tiếp cận khác.
daniero

Có bạn đi; Tôi nghĩ rằng cái này hoạt động như mong đợi. Thậm chí làm cho nó nhỏ hơn :)
daniero

Trông khá tốt, nhưng nó không tối ưu. 6:15có thể được thực hiện với 16:40nhưng mã của bạn trở lại 24:40 16:24.
Keith Randall

4

Perl - 310 306 294 288 272

Tôi hơi thô lỗ với perl và chưa bao giờ chơi golf mã ... nhưng không có lý do. Char-Count là không có ngắt dòng. Sử dụng perl v5.14.2.

($v,$n)=<>=~/(.+):(.+)/;
($x,$y)=($v,$n);($x,$y)=($y,$x%$y)while$y;
sub f{$p=shift;$p/=$x;for(5,3,2){
while(!($p%$_)){$p/=$_;push@_,$_*8}}
$o="IMPOSSIBLE"if$p!=1;
@_}
@a=f($v);@b=f($n);
if(!$o){for(0..($#b>$#a?$#b:$#a)){
$a[$_]||=8;
$b[$_]||=8;
push@_,"$a[$_]:$b[$_]"}}
print"$o@_\n"

Tôi đang mong đợi các nhà phê bình và gợi ý. Thật không dễ để tìm thấy các mẹo và thủ thuật cho môn đánh gôn (bằng perl).


Bạn có thể lưu 9 ký tự bằng cách loại bỏ $1:$2 -> , nó không bắt buộc trong đầu ra.
DaveRandom

Oh, tôi đọc sai thông số kỹ thuật. Cảm ơn.
Patrick B.

Bạn có thể giảm phát biểu như thế $a[$_]=8 if!$a[$_];để$a[$_]||=8;
ardnew

Dòng mới được tính là một ký tự.
TimTech

Dòng đầu tiên có thể được viết tắt thành ($v,$n)=split/:|\s/,<>;(chưa được kiểm tra).
msh210

2

swi-prolog, 324 250 248 204 byte

Prolog làm khá tốt việc giải quyết một vấn đề như thế này.

m(P):-(g(P,L),!;L='IMPOSSIBLE'),write(L).
g(A:A,''):-!.
g(A:B,L):-A/C/X,C>1,B/C/Y,!,g(X:Y,L);A/C/X,!,B/D/Y,C*D>1,g(X:Y,T),format(atom(L),'~D:~D ~a',[C*8,D*8,T]).
X/Y/Z:-(Y=5;Y=3;Y=2;Y=1),Z is X//Y,Y*Z>=X.

Đầu vào được truyền dưới dạng tham số hạn để vị ngữ m. Đầu ra được ghi vào thiết bị xuất chuẩn. Xin lỗi về dấu vết 'đúng'; đó chỉ là cách thông dịch viên cho tôi biết mọi thứ đều ổn.

?- m(54:20).
24:40 24:16 24:8 
true.

?- m(7:7).
true.

?- m(7:1).
IMPOSSIBLE
true.

2

C, 246 216 213 byte

Trong một nỗ lực (vô ích) để đánh bại giải pháp Prolog của riêng tôi, tôi đã viết lại hoàn toàn giải pháp C.

b,c,d;f(a,b,p){while(c=a%5?a%3?a%2?1:2:3:5,d=b%5?b%3?b%2?1:2:3:5,c*d>1)c<2|b%c?d<2|a%d?p&&printf("%d:%d ",8*c,8*d):(c=d):(d=c),a/=c,b/=d;c=a-b;}main(a){scanf("%d:%d",&a,&b);f(a,b,0);c?puts("IMPOSSIBLE"):f(a,b,1);}

Giải pháp C ban đầu của tôi (246 byte):

#define f(c,d) for(;a%d<1;a/=d)c++;for(;b%d<1;b/=d)c--;
b,x,y,z;main(a){scanf("%d:%d",&a,&b);f(x,2)f(y,3)f(z,5)if(a-b)puts("IMPOSSIBLE");else
while((a=x>0?--x,2:y>0?--y,3:z>0?--z,5:1)-(b=x<0?++x,2:y<0?++y,3:z<0?++z,5:1))printf("%d:%d ",a*8,b*8);}

Đó là một bài tập tốt để chứng minh nó có thể được thực hiện mà không cần xây dựng danh sách.


2

Bình thường, 101 byte

(Hầu như chắc chắn không cạnh tranh trong cuộc thi vì sử dụng ngôn ngữ mới hơn sep / 2012)

D'HJH=Y[)VP30W!%JN=/JN=Y+NY))R,YJ;IneKhm'vdcz\:J"IMPOSSIBLE").?V.t,.-Y.-hK=J.-hKYJ1In.*Npj\:m*8d_Np\ 

Việc thực hiện câu trả lời python của @daniero nhưng được tối ưu hóa cho Pyth.

D'H                               - Define a function (') which takes an argument, H.
   JH                             - J = H (H can't be changed in the function)
     =Y[)                         - Y = []
         V                        - For N in ...
          P30                     - Prime factors of 30 (2,3,5)
             W!%JN                - While not J%N
                  =/JN            - J /= N
                      =Y+NY       - Y = N + Y
                           ))R,YJ - To start of function, return [Y,J]

ENDFUNCTION

If 
         cz\:  - Split the input by the ':'
     m'vd      - ['(eval(d)) for d in ^]
   Kh          - Set K to the first element of the map (before the :)
  e            - The second returned value
             J - The second returned value after the : (The variables are globals)
 n             - Are not equal

Then 
"IMPOSSIBLE" - Print "IMPOSSIBLE"

Else
V                                      - For N in
 .t                1                   - transpose, padded with 1's
             .-hKY                     - 1st function first return - 2nd function first return
           =J                          - Set this to J
       .-hK                            - 1st function first return - ^
    .-Y                                - 2nd function first return - ^
   ,              J                    - [^, J]
                                         (Effectively XOR the 2 lists with each other)
                    I                  - If
                     n.*N              - __ne__(*N) (if n[0]!=n[1])
                         pj\:m*8d_N    - print ":".join([`d*8` for d in reversed(N)])
                                   p\  - print a space seperator

Hãy thử nó ở đây

Hoặc kiểm tra mọi trường hợp


0

ES6, 230 byte

x=>([a,b]=x.split`:`,f=(x,y)=>y?f(y,x%y):x,g=f(a,b),d=[],a/=g,f=x=>{while(!(a%x))a/=x,d.push(x*8)},[5,3,2].map(f),c=d,d=[],a*=b/g,[5,3,2].map(f),a>1?'IMPOSSIBLE':(c.length<d.length?d:c).map((_,i)=>(c[i]||8)+':'+(d[i]||8)).join` `)

Một trong những sân golf dài nhất của tôi, vì vậy tôi phải làm gì đó sai ... Ungolfed:

x => {
    [a, b] = x.split(":");
    f = (x, y) => y ? f(y, x % y) : x; // GCD
    g = f(a, b);
    f = x => {
        r = [];
        while (!(x % 5)) { x /= 5; r.push(5); }
        while (!(x % 3)) { x /= 3; r.push(3); }
        while (!(x % 2)) { x /= 2; r.push(2); }
        if (x > 1) throw "IMPOSSIBLE!";
        return r;
    }
    c = f(a);
    d = f(b);
    r = [];
    for (i = 0; c[i] || d[i]; i++) {
        if (!c[i]) c[i] = 8;
        if (!d[i]) d[i] = 8;
        r[i] = c[i] + ":" + d[i];
    }
    return r.join(" ");
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.