อัตราส่วนเลโก้เกียร์


23

ฉันกำลังสร้างหุ่นยนต์เลโก้ยักษ์และฉันจำเป็นต้องสร้างอัตราส่วนเกียร์พิเศษบางอย่างโดยใช้ชุดเกียร์ ฉันมีจำนวนมากของเกียร์ที่มีขนาดเลโก้เกียร์ธรรมดา: 8, 16, 24 หรือ 40 ฟัน เขียนโปรแกรมที่ฉันสามารถใช้ในการใส่อัตราส่วนการใส่เกียร์และโปรแกรมบอกฉันว่าควรใช้การรวมกันของเกียร์เพื่อให้ได้อัตราส่วนที่ต้องการ

อัตราส่วนการป้อนข้อมูลจะถูกระบุในการป้อนข้อมูลมาตรฐาน (หรือเทียบเท่าภาษาของคุณ) ที่มีจำนวนเต็มสองจำนวนคั่นด้วยลำไส้ใหญ่ อัตราส่วนของa:bวิธีการที่เพลาส่งออกควรเปลี่ยนa/bเวลาเป็นเร็วเป็นเพลาอินพุต

เอาต์พุตไปยังเอาต์พุตมาตรฐานควรเป็นบรรทัดเดียวที่มีรายการอัตราส่วนเกียร์ว่างโดยคั่นด้วยช่องว่างในรูปแบบx:yที่xขนาดของเกียร์บนเพลาอินพุตและyเป็นขนาดของเกียร์บนเพลาเอาท์พุท คุณต้องใช้จำนวนเกียร์ต่ำสุดเท่าที่จะเป็นไปได้สำหรับอัตราส่วนที่กำหนด แต่ละคนxและต้องเป็นหนึ่งในy8,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 อัตราส่วนควรจะเป็น 40: 8 แทนที่จะเป็น 8:40 หรือไม่? หรือเป็นอัตราส่วนซ้ายมือของฟันเฟืองที่มีประสิทธิภาพต่ออัตราส่วนฟันซี่เกียร์ที่คุณต้องการ
DavidC

คำถามที่น่าสนใจ ... 1:5 -> 8:40และ10:1 -> 40:8สมเหตุสมผล แต่คนอื่นไม่มาก
Rob

@DavidCarraher: ฉันเดาว่าคุณสามารถกำหนดได้ทั้งสองทาง ฉันพยายามที่จะสอดคล้องภายใน 1:5หมายถึงเพลาส่งออกช้าลง 5 เท่าและเฟืองฟัน 8 อันที่อินพุทและเฟืองเฟือง 40 อันที่เอาต์พุตนั้นเกิดขึ้น
Keith Randall

@ MikeDtrick: 10:1 -> 40:8 16:8ใช่ไม่ใช่สิ่งที่คุณพูด แล้วคนอื่นสับสนกับคุณอย่างไร 9:4จะดำเนินการทำ3:2สองครั้ง จะดำเนินการใช้3:2 24:16
Keith Randall

2
@ MikeDtrick: ใช่สำหรับคำถามแรกของคุณ ในการรับ 10: 1 คุณสามารถทำได้ 5: 1 (ใช้ 40 ฟัน / 8 ซี่) จากนั้น 2: 1 (ใช้ 16 ฟัน / 8 ซี่) 7:7เหมือนกัน1:1ดังนั้นจึงไม่จำเป็นต้องใช้อุปกรณ์ในการติดตั้ง
Keith Randall

คำตอบ:


4

Python - 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
ugoren

23:12ไม่ทำงานเช่น
Keith Randall

เห็นดี มันผ่านไปได้ตั้งแต่ 12 หารได้ การเพิ่มelif i!=1:return[]ไปที่ต้นฉบับแก้ปัญหา แต่แนะนำอีกหนึ่ง $ python gears.py <<< 21:28=> 24:16.. ฉันจะดูมัน ดูเหมือนว่าปัญหาจะไม่ง่ายอย่างนั้นเลย DI คิดว่ารหัสต้องยาวขึ้นหรือฉันต้องการวิธีการอื่น
daniero

ไปแล้ว ฉันคิดว่าอันนี้ใช้งานได้ตามที่คาดไว้ ทำให้มันเล็กลง :)
daniero

ดูดีทีเดียว แต่ไม่เหมาะ 6:15สามารถทำได้ด้วย16:40แต่รหัสของคุณกลับ24:40 16:24มา
Keith Randall

4

Perl - 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"

ฉันรอคอยที่จะวิจารณ์และคำแนะนำ มันไม่ง่ายเลยที่จะหาเคล็ดลับและกลเม็ดสำหรับการเล่นกอล์ฟ


คุณสามารถบันทึก 9 ตัวอักษรโดยการลบ$1:$2 -> มันไม่จำเป็นในการส่งออก
DaveRandom

โอ้ฉันอ่านสเป็คไม่ถูกต้อง ขอบคุณ
แพทริค B.

คุณสามารถลดงบเช่น$a[$_]=8 if!$a[$_];ไป$a[$_]||=8;
ardnew

ขึ้นบรรทัดใหม่นับเป็นหนึ่งอักขระ
Timtech

บรรทัดแรกสามารถย่อไปยัง($v,$n)=split/:|\s/,<>;(ยังไม่ทดลอง)
msh210

2

swi-prolog, 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.

mการป้อนข้อมูลจะถูกส่งเป็นพารามิเตอร์ระยะกริยา เอาต์พุตถูกเขียนไปยัง stdout ขออภัยเกี่ยวกับ 'จริง' ต่อท้าย; นั่นเป็นเพียงวิธีการของล่ามให้ฉันรู้ว่าทุกอย่างเรียบร้อยดี

?- 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 ไบต์

(เกือบจะแน่นอนว่าไม่ใช่การแข่งขันในการแข่งขันที่ใช้ภาษาใหม่กว่า 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\ 

การใช้คำตอบหลาม @danieroแต่ได้รับการปรับให้เหมาะสมที่สุดสำหรับ 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` `)

หนึ่งในสนามกอล์ฟที่ยาวที่สุดของฉันดังนั้นฉันต้องทำอะไรผิดไป ... 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.