Przełożenia Lego


23

Buduję gigantycznego robota Lego i muszę wygenerować określone przełożenia przy użyciu zestawu kół zębatych. Mam wiele kół zębatych ze zwykłymi rozmiarami kół LEGO: 8, 16, 24 lub 40 zębów. Napisz program, którego mogę użyć, w którym wprowadzę przełożenie, a program powie mi, jakiej kombinacji biegów powinienem użyć, aby uzyskać żądany przełożenie.

Współczynnik wejściowy zostanie określony na standardowym wejściu (lub w twoim języku) za pomocą dwóch liczb całkowitych oddzielonych dwukropkiem. Stosunek a:boznacza, że ​​wał wyjściowy powinien obracać się a/btak szybko, jak wał wejściowy.

Dane wyjściowe na standardowe dane wyjściowe powinny być pojedynczą linią zawierającą rozdzieloną spacjami listę przełożeń przekładni, w postaci x:ygdzie xjest wielkość koła zębatego na wale wejściowym i ywielkość koła zębatego na wale wyjściowym. Musisz użyć minimalnej możliwej liczby biegów dla danego przełożenia. Każdy xi ymusi być jednym z 8,16,24,40.

przykłady:

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

Jeśli żądane przełożenie jest niemożliwe, wydrukuj „NIEMOŻLIWE”. Jeśli nie są wymagane żadne koła zębate, wydrukuj pusty ciąg.

To jest golf golfowy, wygrywa najkrótsza odpowiedź.


Czy stosunek zębów nie jest odwrotnie proporcjonalny do prędkości kątowej? Na przykład, jeśli pożądana prędkość wyjściowa wynosi 1: 5, czy stosunek nie powinien wynosić 40: 8 zamiast 8:40? A może lewostronny stosunek efektywnego uzębienia do rzeczywistego stosunku uzębienia, jaki chcesz?
DavidC,

Interesujące pytanie ... 1:5 -> 8:40i 10:1 -> 40:8ma sens, ale inni nie tak bardzo.
Rob

@DavidCarraher: Myślę, że możesz to zdefiniować w dowolny sposób. Starałem się być wewnętrznie konsekwentny. 1:5oznacza, że ​​wał wyjściowy obraca się 5-krotnie wolniej, a koło zębate 8 zębów na wejściu i koło zębate 40 zębów na wyjściu sprawia, że ​​tak się dzieje.
Keith Randall,

@MikeDtrick: cóż 10:1 -> 40:8 16:8, nie to, co powiedziałeś. A co z innymi, mylisz się? 9:4jest realizowane 3:2dwukrotnie. 3:2jest implementowany za pomocą 24:16.
Keith Randall,

2
@MikeDtrick: Tak na twoje pierwsze pytanie. Aby uzyskać 10: 1, możesz zrobić 5: 1 (używając 40 zębów / 8 zębów), a następnie 2: 1 (używając 16 zębów / 8 zębów). 7:7jest taki sam jak 1:1, więc nie wymaga żadnych narzędzi do wdrożenia.
Keith Randall

Odpowiedzi:


4

Python - 204

Ok, pójdę pierwszy:

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]
edytować:

Aby „zoptymalizować” wynik, można go dodać przed printinstrukcją,

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

łączna liczba maksymalnie 266 znaków , jak sądzę.


1
<1może zastąpić ==0. Ponadto, if b:a=...return amoże być return b and...or a.
ugoren

Nie działa np 23:12.
Keith Randall,

Dobrze zauważony. Przechodzi, ponieważ 12 można podzielić. Dodanie elif i!=1:return[]do oryginału rozwiązuje problem, ale wprowadza inny. $ python gears.py <<< 21:28=> 24:16.. Zajmę się tym. Wygląda na to, że problem nie był wcale taki prosty: DI Myślę, że kod musi być jeszcze dłuższy, albo potrzebuję innego podejścia.
daniero

Proszę bardzo; Myślę, że ten działa zgodnie z oczekiwaniami. Nawet zmniejszyło to :)
daniero

Wygląda całkiem dobrze, ale nie jest optymalny. 6:15można to zrobić, 16:40ale kod zwraca 24:40 16:24.
Keith Randall,

4

Perl - 310 306 294 288 272

Jestem trochę zardzewiały z perlem i nigdy nie grałem w golfa ... ale bez wymówek. Liczba znaków nie zawiera podziałów linii. Korzystanie z Perla 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"

Nie mogę się doczekać krytyków i wskazówek. Nie jest tak łatwo znaleźć porady i wskazówki dotyczące gry w golfa kodowego (w perlu).


Możesz zapisać 9 znaków usuwając $1:$2 -> , nie jest to wymagane na wyjściu.
DaveRandom

Och, źle odczytałem specyfikację. Dzięki.
Patrick B.

Można zmniejszyć wypowiedzi jak $a[$_]=8 if!$a[$_];do$a[$_]||=8;
ardnew

Nowe linie liczą się jako jeden znak.
Timtech

Pierwszy wiersz może być skrócony do ($v,$n)=split/:|\s/,<>;(niesprawdzony).
msh210

2

swi-prolog, 324 250 248 204 bajtów

Prolog radzi sobie całkiem dobrze w rozwiązywaniu takich problemów.

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.

Dane wejściowe są przekazywane jako parametr określający predykat m. Dane wyjściowe są zapisywane na standardowe wyjście. Przepraszam za końcowe „prawda”; to tylko sposób, w jaki tłumacz mówi mi, że wszystko jest w porządku.

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

?- m(7:7).
true.

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

2

C, 246 216 213 bajtów

W (daremnej) próbie pokonania własnego rozwiązania Prolog całkowicie przepisałem rozwiązanie 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);}

Moje oryginalne rozwiązanie C (246 bajtów):

#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);}

Miło było udowodnić, że można to zrobić bez list budynków.


2

Pyth, 101 bajtów

(Niemal na pewno nie konkuruje w konkursie, ponieważ używa języka nowszego niż wrzesień / 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\ 

Implementacja odpowiedzi Pythona @daniero, ale częściowo zoptymalizowana pod kątem 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

Wypróbuj tutaj

Lub przetestuj każdy przypadek


0

ES6, 230 bajtów

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` `)

Jeden z moich najdłuższych pól golfowych, więc musiałem zrobić coś złego ... 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(" ");
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.