レゴギア比


23

巨大なレゴロボットを構築していますが、ギアのセットを使用して特定のギア比を生成する必要があります。一般的なレゴギアサイズ(8、16、24、または40歯)のギアがたくさんあります。ギア比を入力する場所で使用できるプログラムを作成すると、プログラムは、要求された比を得るために使用するギアの組み合わせを教えてくれます。

入力比率は、コロンで区切られた2つの整数を使用して、標準入力(または言語の同等)で指定されます。比率とa:bは、出力軸がa/b入力軸と同じくらい速く回転することを意味します。

標準出力に出力の形態におけるギヤ比のスペースで区切られたリストを含む単一の行、でなければならないx:y場合x、入力軸上のギヤのサイズであり、y出力軸上の歯車の大きさです。指定された比率のギアの最小数を使用する必要があります。それぞれxyのいずれかでなければなりません8,16,24,40

例:

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

希望のギア比が不可能な場合は、「IMPOSSIBLE」を印刷します。ギアが必要ない場合は、空の文字列を印刷します。

これはコードゴルフで、最短回答が勝ちます。


歯の比率は角速度に反比例していませんか?したがって、たとえば、目的の入出力速度が1:5の場合、比率は8:40ではなく40:8にすべきではありませんか?または、左手の比率は、実際のギアの歯の比率に対する有効なギアの歯ですか?
DavidC

興味深い質問... 1:5 -> 8:4010:1 -> 40:8理にかなっていますが、他の人はそれほど多くありません。
ロブ

@DavidCarraher:どちらの方法でも定義できると思います。私は内部的に一貫性を保とうとしました。 1:5は、出力シャフトの回転が5倍遅くなることを意味し、入力の8歯歯車と出力の40歯歯車がそれを実現します。
キースランドール

@MikeDtrick:まあ、10:1 -> 40:8 16:8あなたが言ったことではありません。他の人はあなたを混乱させますか? 2回9:4実行され3:2ます。 3:2を使用して実装され24:16ます。
キースランドール

2
@MikeDtrick:最初の質問にはい。10:1を取得するには、5:1(40歯/ 8歯を使用)から2:1(16歯/ 8歯を使用)を実行します。 はと7:7同じ1:1であるため、実装にギアは必要ありません。
キースランドール

回答:


4

パイソン-204

はい、最初に行きます:

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]
編集:

出力を「最適化」するには、これをprintステートメントの前に追加します。

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

合計で266文字になりました。


1
<1交換でき==0ます。また、if b:a=...return aすることができますreturn b and...or a
ウゴレン

などでは機能しません23:12
キースランドール

よく見分けられます。12は割り切れるので、それは通過します。elif i!=1:return[]オリジナルに追加すると問題は解決しますが、別の問題が発生します。$ python gears.py <<< 21:28=> 24:16..調べます。結局のところ、問題はそれほど単純ではなかったように見えます:DIコードをさらに長くする必要があると思うか、別のアプローチが必要です。
daniero

そこに行きます。これは期待通りに動作すると思います。さらに小さくした:)
daniero

かなり良いように見えますが、最適ではありません。 6:15で行うことができます16:40が、コードは戻ります24:40 16:24
キースランドール

4

パール- 310 306 294 288 272

私はperlに少しさびていて、コードゴルフをしたことはありません...言い訳はしませんでした。文字カウントには改行がありません。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"

批評家やヒントを楽しみにしています。code-golf(perl)のヒントやコツを見つけるのはそれほど簡単ではありません。


を削除すること$1:$2 -> で9文字を保存できますが、出力では必要ありません。
-DaveRandom

ああ、仕様を読み間違えました。ありがとう。
パトリックB.

あなたのような文を減らすことができます$a[$_]=8 if!$a[$_];$a[$_]||=8;
ardnew

改行は1文字としてカウントされます。
ティムテック14年

最初の行は($v,$n)=split/:|\s/,<>;(テストされていない)に短縮できます。
msh210

2

SWI-プロローグ、324の 250 248 204バイト

プロローグは、このような問題の解決に非常に適しています。

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.

入力は、用語パラメーターとしてpredicateに渡されますm。出力はstdoutに書き込まれます。末尾の「true」については申し訳ありません。それは通訳者がすべてがうまくいったことを私に知らせる方法です。

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

?- m(7:7).
true.

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

2

C、246の 216 213バイト

私自身のPrologソリューションを打ち負かす(無駄な)試みで、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);}

私の元のCソリューション(246バイト):

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

リストを作成せずに実行できることを証明するのは良い練習でした。


2

Pyth、101バイト

(ほぼ間違いなく、2012年9月より新しい言語を使用しているため、コンテストで競合していません)

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

@daniero 'python回答の実装ですが、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

ここで試してみてください

またはすべてのケースをテストします


0

ES6、230バイト

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

私の最も長いゴルフの1つなので、何か間違ったことをしたに違いありません... 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(" ");
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.