คำสั่ง“ สำหรับ” ของคุณเอง


38

การเรียนการสอน "สำหรับ" ของคุณเอง

สมมติว่าคุณมีอินพุตต่อไปนี้: a, b, c, d

อินพุตสามารถอยู่ในบรรทัดเดียวโดยใช้รูปแบบใด ๆ "a / b / c / d" หรือ "a, b, c, d" ฯลฯ

คุณสามารถมี 4 อินพุต

คุณต้องโค้ดพฤติกรรมดังต่อไปนี้ (รหัสหลอกที่นี่):

var i = <a>
while (i <b> <c>)
    print i
    i = i + <d>
    print "\n"

นี่คือกรณีทดสอบบางส่วน:

input : 1,<,10,1
output :
1
2
3
4
5
6
7
8
9

อีกหนึ่ง :

input : 20,>,10,1
output :
20
21
22
23
24
25
26
27
...
infinite loop / program crashes
  • aเป็นจำนวนเต็ม , iค่าเริ่มต้นของ

  • bเป็นสตริงหรืออักขระไม่สามารถเป็นอย่างอื่นตัวเปรียบเทียบที่ใช้ในเงื่อนไขสิ้นสุดของ forลูป

    bสามารถและต้องเป็นหนึ่งในสตริงต่อไปนี้:

    - ">"
    - "<"
    
  • cเป็นจำนวนเต็มจำนวนที่ใช้ในเงื่อนไขสิ้นสุดของfor ลูป

  • dเป็นจำนวนเต็มที่เพิ่มให้กับ i ในทุก ๆ ลูป

นี่คือรหัสกอล์ฟคำตอบที่สั้นที่สุดชนะ!


1
สามารถส่งคืนหมายเลขจากฟังก์ชันเป็นรายการ / ลำดับแทนที่จะพิมพ์ไปยัง stdout ได้หรือไม่?
smls

@smls ไม่ขออภัยเอาต์พุตต้องเป็นตัวอย่าง!
Sygmei

1
มันบอกว่ารหัสของฉันควรเป็นไปตามหลอกรหัสและมีprint "\n"แต่ฉันกำลังใช้การแจ้งเตือนของจาวาสคริปต์สำหรับแต่ละบรรทัด นั่นจะเป็นที่ยอมรับหรือฉันจะต้องใช้ console.log แทนที่จะทำให้คำตอบของฉันนานขึ้น?

2
คุณสามารถใช้ฟังก์ชั่นการแจ้งเตือนเป็นวิธีในการ ouput แต่คุณไม่สามารถใช้การแจ้งเตือนหลายรายการ สิ่งที่ต้องการalert("23\n24\n25");จะทำงานในขณะที่alert("23"); alert("24"); alert(25);จะไม่
Sygmei

คำตอบ:


25

JavaScript (ES6),  44  43 56 ไบต์

บันทึก 1 ไบต์ด้วย ETHproductions
แก้ไข: แก้ไขเพื่อให้สอดคล้องกับข้อกำหนดของผลลัพธ์

(a,b,c,d)=>{for(s='';eval(a+b+c);a+=d)s+=a+`
`;alert(s)}

ทดสอบ


ใช้ขอบเขตได้ดี!
ETHproductions

ฉันคิดว่าคุณสามารถจัดเรียงใหม่evalเพื่อบันทึกไบต์:(a,b,c,d)=>{for(;eval(a+b+c);a+=d)alert(a)}
ETHproductions

@ETHproductions อ่าใช่ ทำได้ดีนี่!
Arnauld

5
นั่นคือ 44 ด้วยตู!
aross

สิ่งนี้ไม่เป็นไปตามข้อกำหนดที่ผลลัพธ์เป็นบรรทัดต่อบรรทัดด้วย U + 000A หลังจากทุกบรรทัด
Joey

17

Javascript (ES6), 47 42 48 ไบต์

ต้องการสร้างเวอร์ชัน แต่มีบางคนเร็วขึ้นดังนั้นนี่คือรุ่นเรียกซ้ำ

(b,c,d)=>F=a=>eval(a+b+c)&&console.log(a)|F(a+d)

คุณต้องเพิ่มก่อนและเรียกมันเหมือนf=f(b,c,d)(a)

ขอบคุณ Arnauld สำหรับสนามกอล์ฟที่ยอดเยี่ยมมาก

alertเปลี่ยนเป็นconsole.logเนื่องจากข้อกำหนดคุณลักษณะของเอาต์พุต


@Arnauld ขอบคุณนั่นเป็นสนามกอล์ฟที่น่าสนใจ ฉันแค่ถามเขาดังนั้นลองมาดูกันว่าเขายอมรับหรือไม่

ดีใจที่ได้เห็นมันได้รับการยอมรับ ;)
Arnauld

สิ่งนี้ไม่เป็นไปตามข้อกำหนดที่ผลลัพธ์เป็นบรรทัดต่อบรรทัดด้วย U + 000A หลังจากทุกบรรทัด
Joey

@ โจอี้นั่นเป็นเพียงโค้ดหลอก แต่ฉันจะถาม OP เกี่ยวกับเรื่องนี้

@Masterzagh: มีคำถามเกี่ยวกับรูปแบบเอาต์พุตอื่นที่ถูกปฏิเสธแล้ว
Joey

15

ทุบตีบริสุทธิ์ 35

ฉันคิดว่ามัน OK เพียงแค่เสียบพารามิเตอร์เข้ากับมาตรฐานสำหรับลูป:

for((i=$1;i$2$3;i+=$4));{ echo $i;}

ลองมันออนไลน์


ฮ่าฮ่าทุบตีทำให้เป็นเรื่องง่ายจริงๆ
Sygmei

13

เยลลี่ 12 ไบต์

Ṅ+⁶µ⁴;⁵¹vµ¿t

ลองออนไลน์!

เจลลี่มีหลายวิธีที่จะทำการวนซ้ำสร้างช่วง ฯลฯ อย่างไรก็ตามการสะท้อนพฤติกรรมของ C ++ นั้นค่อนข้างยากเนื่องจากกรณีพิเศษเช่นการเพิ่มขึ้นเป็น 0 การวนซ้ำสิ้นสุดก่อนที่จะเริ่ม (เนื่องจากความไม่เท่าเทียมกันถูกย้อนกลับ ) และการเพิ่มขึ้นไปในทิศทางที่ไม่ถูกต้อง (จึงหมายถึงสภาพทางออกของลูปไม่สามารถทำได้ตามธรรมชาติ) ดังนั้นวิธีนี้จึงเป็นการแปลโดยตรงของ C ++ ถึงแม้ว่ามันจะทำให้มันค่อนข้างต่ำกว่าปกติในโปรแกรมของเยลลี่ก็ตาม โชคดีที่ C ++ มีพฤติกรรมที่ไม่ได้กำหนดในจำนวนเต็มล้นที่ลงนาม (คำถามใช้int) ซึ่งหมายความว่าโปรแกรมสามารถทำอะไรก็ได้ในกรณีนั้นและทำให้ไม่จำเป็นต้องพยายามเลียนแบบพฤติกรรมล้น

คำอธิบาย

Ṅ+⁶µ⁴;⁵¹vµ¿t
   µ     µ¿   While loop; while ((⁴;⁵¹v) counter) do (counter = (Ṅ+⁶)counter).
    ⁴;⁵       Second input (b) appended to third input (c), e.g. "<10"
        v     Evaluate, e.g. if the counter is 5, "<10" of the counter is true
       ¹      No-op, resolves a parser ambiguity
Ṅ             Output the counter, plus a newline
 +⁶           Add the fourth input (d)
           t  Crashes the program (because the counter is not a list)

การขัดจังหวะโปรแกรมเป็นวิธีที่ยากที่สุดในการปิดเอาต์พุตโดยนัยของเจลลี่ (มิฉะนั้นจะส่งออกค่าสุดท้ายของตัวนับ) มันสร้างพวงของข้อผิดพลาด messges บน stderr แต่โดยปกติเราพิจารณาว่าจะได้รับอนุญาต

อนึ่งตัวนับลูปจะเริ่มต้นด้วยค่าปัจจุบันก่อนที่ลูปจะเริ่มต้น เมื่อลูปปรากฏที่จุดเริ่มต้นของโปรแกรมนั่นจะเป็นอินพุตแรก


คุณสามารถเปลี่ยนtเป็นไม่มีข้อผิดพลาด การ dequeue ส่งผลให้เกิดรายการที่ว่างซึ่งการพิมพ์โดยนัยของเยลลี่ไม่ทำให้เกิดผล
Jonathan Allan

@JanathanAllan: ไม่เช่นนั้นสิ่งที่จริง ๆ แล้วคือการสร้างช่วงจาก 2 ถึงค่าที่กำหนดซึ่งสามารถมองเห็นได้อย่างชัดเจนในการพิมพ์โดยนัย

อ๊ะฉันต้องทดสอบทฤษฎีนั้นด้วยการวนซ้ำที่สิ้นสุดในดินแดนลบ แน่นอนช่วงถูกสร้างขึ้นโดยปริยาย
Jonathan Allan

เอ่อนี่คือ 12 ตัวอักษร แต่มันไม่ได้ 12 ไบท์ใช่มั้ย
Cruncher

@Cruncher: Jelly ใช้การเข้ารหัสของตัวเองซึ่งอักขระแต่ละตัวที่ใช้โดยภาษานั้นจะแสดงเป็นไบต์เดียว (ใช้เพียง 256 ตัวอักษรเท่านั้น) เหตุผลที่ไม่ใช้สิ่งที่รู้จักกันดีกว่าเช่นรหัสหน้า 437 คือเพื่อให้พิมพ์ได้ง่ายขึ้น (ฉันหมายถึงไม่ใช่ประเภทที่ง่าย แต่เป็นภาษาที่ง่ายกว่าภาษาอย่าง gs2) เลขฐานสิบหกของโปรแกรมนี้จะมีความยาว 12 ไบต์



9

Java, 58 ไบต์

(a,b,c,d)->{for(;b>61?a>c:a<c;a+=d)System.out.println(a);}

14
มีเหตุผลในการสร้างiหรือไม่? คุณสามารถข้ามส่วนการเริ่มต้นและเพียงแค่ใช้a? นอกจากนี้การใช้ค่า ASCII ของ '>' (62) จะบันทึกไบต์
Riley

6
การติดตามความคิดเห็นของ Riley คุณสามารถทำได้b>61
Kritixi Lithos

ฉันไม่เชื่อว่าคอมไพล์นี้
ChiefTwoPencils

@ChiefTwoPencils มันเป็นฟังก์ชั่น คุณต้องเขียนโปรแกรมทดสอบรอบ ๆ เพื่อรวบรวมมัน
wizzwizz4

@ wizzwizz4 ชัด แต่นั่นก็ยังไม่ทำงาน ลองยิงดู นอกจากนี้ความเข้าใจของฉันคือจำนวนไบต์ทั้งหมดที่จำเป็นในการเรียกใช้
ChiefTwoPencils

7

05AB1E , 22 20 ไบต์

[D²`'>Q"‹›"è.V_#D,³+

ลองออนไลน์!

คำอธิบาย

[                       # start loop
 D                      # copy top of stack (current value of a)
  ²`                    # push b,c to stack
    '>Q                 # compare b to ">" for equality
       "‹›"             # push this string
           è            # index into the string with this result of the equality check
            .V          # execute this command comparing a with c
              _#        # if the condition is false, exit loop (and program)
                D,      # print a copy of the top of the stack (current value of a)
                  ³+    # increment top of stack (a) by d

1
รูปแบบการป้อนข้อมูลใด ๆ ที่ได้รับการยอมรับดังนั้นรุ่นที่สองคือโอเค :)
Sygmei

7

SmileBASIC ขนาด 53 ไบต์

INPUT A,B$,C,D
S=ASC(B$)-61WHILE S*A>S*C?A
A=A+D
WEND

คำอธิบาย:

INPUT A,B$,C,D
IF B$=="<" THEN S=-1 ELSE S=1 'get comparison direction
I=A
WHILE S*I>S*C 'loop while I is less than/greater than the end
 PRINT I
 INC I,D
WEND

สิ่งนี้ใช้ความจริงที่X<Yเหมือนกับ-X>-Y


ฉันจะไว้วางใจคุณหนึ่งนี้ผมไม่ได้มี 3DS เพื่อทดสอบ :)
Sygmei

ฉันมีคอมพิวเตอร์ Petit ความคิดที่ยอดเยี่ยมมาก! ผมจะพยายามบางอย่างเช่นบางครั้งนี้ ...
หลาม-B5

คุณสามารถใช้READคำสั่งบันทึก 1 ไบต์
ckjbgames

@ckjbgames อย่างไร
12Me21

@ 12Me21 ตรวจสอบคู่มือ SmileBASIC ควรอยู่ในรายการคำแนะนำสำหรับ SmileBASIC
ckjbgames

6

ซ้อนกัน , 34 ไบต์

@d@c@b[show d+][:c b tofunc!]while

ลองออนไลน์! (รวมการทดสอบ) นี่เป็นฟังก์ชันที่คาดว่าสแต็กจะมีลักษณะดังนี้:

a b c d

ตัวอย่างเช่น:

1 '<' 10 2
@d@c@b[show d+][:c b tofunc!]while

คำอธิบาย

@d@c@b[show d+][:c b tofunc!]while
@d@c@b                               assign variables
               [............]while   while:
                :c                   duplicate "i" and push c
                   b tofunc!         convert b to a function and execute it
      [.......]                      do:
       show                          output "i" without popping
            d+                       and add the step to it

4

C ++, 80

อ๊ะนี้เป็นไม่ได้C++ Cคำถามนั้นสับสนเล็กน้อย

void f(int a,char b,int c,int d){for(;b==62?a>c:a<c;a+=d)cout<<a<<endl;}

นี่คือ C หรือ C ++ หรือไม่
betseg

10
การใช้ C ++ ใด (ฉันอยากรู้ว่าคุณจะได้อะไรที่คล้ายกันusing namespace stdฟรี)
H Walters

ไม่iต้องเริ่มaเลย0ใช่มั้ย คุณสามารถใช้aและข้ามiไปเลยและใช้ค่า ASCII ของ '>' for(;b==62?a>c:a<c;a+=d)
Riley

ใช้งานไม่ได้f(1,'<'3,1);
Roman Gräf

Ack ... ใช่ต้องใช้คณิตศาสตร์ทั้งสองด้าน for(b-=61;b*a>b*c;a+=d)ใช้ได้กับไบต์เดียว แต่ก็เช่นfor(;b-62?a<c:a>c;a+=d)กัน
H Walters



4

Pip 14 ไบต์

W Va.b.ca:d+Pa

รับอาร์กิวเมนต์บรรทัดรับคำสั่งสี่ข้อ < > = <= >= !=รองรับตัวเลขที่ติดลบและจุดลอยและผู้ประกอบการเปรียบเทียบ ลองออนไลน์!

                a,b,c,d are cmdline args
W               While loop with the following condition:
  Va.b.c          Concatenate a,b,c and eval
            Pa  Print a with newline (expression also returns value of a)
        a:d+    Add d to that and assign back to a

4

เยลลี่ขนาด 8 ไบต์

ḢṄ+⁹;µV¿

นี่คือลิงก์ dyadic ที่ใช้a, b, cเป็นอาร์กิวเมนต์ซ้ายและdเป็นลิงก์ขวา ผลลัพธ์อาจไม่สิ้นสุดและไปที่ STDOUT

ลองออนไลน์!

มันทำงานอย่างไร

ḢṄ+⁹;µV¿  Dyadic link.
          Left argument:  a,b,c (integer, character, integer)
          Right argument: d     (integer)

       ¿  While...
      V     the eval atom applied to a,b,c returns 1:
     µ       Combine the links to the left into a chain and apply it to a,b,c.
Ḣ              Head; pop and yield a from a,b,c.
 Ṅ             Print a, followed by a linefeed.
  +⁹           Add a and the right argument (d) of the dyadic link.
    ;          Concatenate the result and the popped argument of the chain,
               yielding a+d,b,c.

อาร์กิวเมนต์บรรทัดคำสั่งใช้ไวยากรณ์ Python และไม่สามารถแยกความแตกต่างระหว่างอักขระและสตริงซิงเกิล หากคุณต้องการใช้ CLA คุณจะต้องแทรกFเพื่อย่ออาร์เรย์
Dennis

2
ตอนนี้ฉันต้องการลบความคิดเห็นของฉันครึ่งหนึ่งเนื่องจากมันล้าสมัยในขณะที่รักษาอีกครึ่งไว้ ฉันเดาว่าฉันจะทำซ้ำครึ่งที่เกี่ยวข้องและลบส่วนที่เหลือ: "โอ้คุณได้กำหนดมันเป็นฟังก์ชั่นเพื่อให้คุณสามารถเพิกเฉยต่อการส่งออกโดยนัยภายใต้กฎ PPCG ฉันควรจะคิดอย่างนั้น"

4

Python 2 , 45 ไบต์

exec"i=%d\nwhile i%c%d:print i;i+=%d"%input()

ลองออนไลน์!

การใช้งานสเป็คที่แท้จริงมาก รับเท็มเพลตโค้ด, ทดแทนในอินพุตผ่านการจัดรูปแบบสตริงและดำเนินการ


4

Plain TeX, 88 ไบต์

\newcount\i\def\for#1 #2 #3 #4 {\i#1\loop\the\i\endgraf\advance\i#4\ifnum\i#2#3\repeat} 

คำสั่ง\forจัดเตรียมฟังก์ชันที่ร้องขอ บันทึกสิ่งนี้เป็นfor.texจากนั้นเรียกใช้แล้วป้อนค่าตัวแปรที่บรรทัดคำสั่ง: pdftex '\input for \for 1 < 5 1 \bye'ค่าตัวแปรต้องคั่นด้วยช่องว่าง


4

Python 3, 61 ไบต์

หนึ่งในสายการบิน:

e=input;exec(f'i={e()}\nwhile i{e()}{e()}:print(i);i+={e()}')

ยินดีต้อนรับสู่เว็บไซต์! การใช้คุณสมบัติการแก้ไขสตริงตัวอักษรใหม่ ฉันคิดว่าคุณอาจบันทึกไบต์ด้วยการแทนที่\tด้วยช่องว่าง
0 '

ขอบคุณขนาดยังคงเดิมหลังจากลบ \ n \ t หลังจากที่สาม e ()
G-Ox7cd




3

dc , 47 ไบต์

dc , 48 ไบต์

นอกจากนี้ยังทุบตีสาธารณูปโภค + Unix, 29 ไบต์

dc (47 ไบต์):

1sb[_1sb]s zz?sdlb*sc[pld+lnx]sl[dlb*lcr<l]dsnx

ลองออนไลน์!

โปรดทราบว่าจะต้องป้อนตัวเลขลบด้วยเครื่องหมายขีดล่างแทนเครื่องหมายลบเพราะนั่นคือวิธีที่ dc ยอมรับอินพุตตัวเลข ดังนั้นเขียนเช่น _5 แทน -5


dc ไม่สามารถอ่านอักขระหรือสตริงอินพุตในตัวแปรและประมวลผล (มีคำอธิบายโดยละเอียดด้านล่าง) แต่ฉันพบวิธีแก้ไขสองวิธีนี้:

แก้ปัญหา dc 47 ไบต์ทำงานในการป้อนข้อมูลที่มี argument1 และ argument2 กลับมีช่องว่างเป็นตัวคั่น ดังนั้นการนับจาก 1 ถึง (แต่ไม่รวม) 10 ในขั้นตอนที่ 3 จะถูกป้อนเป็น:

< 1 10 3

หากไม่สามารถเปลี่ยนลำดับของข้อโต้แย้งได้ฉันก็ให้วิธีแก้ปัญหาแบบ48 ไบต์ซึ่งเก็บลำดับเดิมของข้อโต้แย้ง อันนี้ใช้zzเป็นตัวคั่นระหว่างอาร์กิวเมนต์ ดังนั้นการนับจาก 1 ถึง (แต่ไม่รวม) 10 ในขั้นตอนที่ 3 อีกครั้งจะใช้บรรทัดอินพุตต่อไปนี้:

1zz<zz10zz3

ในที่สุดความคิดเดียวกันผลผลิตแก้ปัญหาทุบตี 29 ไบต์


รายละเอียดเกี่ยวกับการขาดการประมวลผลสตริงของ dc และวิธีที่โปรแกรมนี้เกี่ยวข้องกับสิ่งนั้น:

การจัดการปัญหานี้ใน dc นั้นเป็นเรื่องยุ่งยากเพราะ dc ไม่ยอมรับสตริงหรืออักขระอินพุตเหมือนกับภาษาส่วนใหญ่ เมื่อ dc อ่านสตริงอินพุตสตริงนั้นจะรันสตริงนั้นทันทีเป็นโปรแกรม dc (แมโคร) จากนั้นละทิ้งสตริง คุณไม่สามารถเก็บอักขระของสตริงในหน่วยความจำและประมวลผลในภายหลังหรือด้วยวิธีอื่นใด สิ่งนี้รบกวนความต้องการที่จะมี '<' หรือ '>' ในอินพุต

ฉันจะแสดงสองวิธีรอบนี้ ในโซลูชันด้านบน (47 ไบต์) เราสลับลำดับของอินพุตสองตัวแรก ตัวคั่นอินพุตคืออักขระเว้นวรรค ตัวอย่างเช่นหากต้องการนับตั้งแต่ 1 ถึง (แต่ไม่รวม) 10 ในขั้นตอนที่ 3 คุณต้องป้อนข้อมูล

< 1 10 3

นี่คือแนวคิดเบื้องหลังโซลูชันนี้:

แมโครใน dc ถูกเก็บไว้ในรีจิสเตอร์และรีจิสเตอร์มีชื่ออักขระเดียว ฉันเก็บแมโครไว้ในรีจิสเตอร์ที่มีชื่อเป็นเพียงอักขระเว้นวรรค

โปรแกรมทำงานโดยกด 0 และ 1 บนสแต็กก่อนรับอินพุต จากนั้นเมื่ออินพุตถูกเรียกใช้เป็นโปรแกรม dc (ซึ่งเป็นสิ่งที่ dc ทำกับบรรทัดอินพุต) อักขระ '<' หรือ '>' จะถูกเรียกใช้งานเป็นคำสั่งซึ่งเป็นการเรียกใช้แมโครตามเงื่อนไขของแมโครที่มีชื่อคือ ถ่านตัวถัดไปหลังจาก '<' หรือ '>' โดยเฉพาะไอเท็มสองอันดับแรกบนสแต็ก หากรายการแรกที่ผุดคือ <(ตามลำดับ>>) รายการที่สองที่ผุดมาโครที่ระบุจะถูกดำเนินการ อักขระถัดไป (หลัง '<' หรือ '>') เป็นช่องว่างดังนั้นมาโครที่เราเก็บไว้ในรีจิสเตอร์ที่มีชื่อคือ space char นั้นเป็นตัวที่ถูกเรียกใช้งานถ้าเงื่อนไขมีอยู่ แต่เราได้ผลัก 0 และ 1 ไปที่สแต็กดังนั้นไอเท็มแรกที่ผุดคือ 1 และไอเท็มที่สองที่ผุดคือ 0 ดังนั้น แมโครจะถูกดำเนินการเฉพาะในกรณีที่การทดสอบตามเงื่อนไขคือ> ไม่ใช่ < สิ่งนี้ช่วยให้เราสามารถแยกความแตกต่างระหว่าง '<' และ '>' ในอินพุต

รายการที่เหลือในบรรทัดเป็นเพียงตัวเลขและ dc จะกดตัวเลขเหล่านั้นตามลำดับบนสแต็ก

นี่คือคำอธิบายโดยละเอียด ส่วนใหญ่แล้วตัวแปรการนับ (i ใน pseudocode ในคำแถลงปัญหา) จะถูกเก็บไว้ที่ด้านบนสุดของสแต็ก

1sb             Store 1 in register b.  (b will end up being 1 for '<', and -1 for '>').
[_1sb]s         Note that there is a space after the second s.  So the space char is the name of a macro which stores -1 in b.
z               Push 0 on the stack.
z               Push 1 on the stack.
?               Accept input in the format above.  This will:
                    - Store 1 or -1 in b, depending on whether you've typed "<" or ">"
                    - Push each of the three numbers in turn on the stack.
sd              Save the increment in register d.
lb*sc           Save either limit or -limit in register c, depending on whether the input started with "<" or ">".
[pld+lnx]sl     Define a macro called l which is the body of our loop:
                    - Prints the top of the stack
                    - Adds the increment to the top of the stack.
                    - Calls macro n (the loop test).

 [dlb*lcr<l]dsn  Define a macro called n which is the test of the loop:
                    It checks to see if i (at the top of the stack) times b is less than c; if so, it calls macro l (looping back).
 x               Execute the loop test macro initially (a while loop needs to have a test at the top before entering the loop the first time).

ในทางกลับกัน OP ระบุไว้:

Input can be in one-line using any format "a/b/c/d" or "a,b,c,d" etc.

ดังนั้นอาจไม่ถูกต้องที่จะเปลี่ยนคำสั่งซื้อและต้องการ b ก่อน a ในอินพุท

นี่คือทางเลือกที่เก็บ a, b, c และ d ตามลำดับดั้งเดิม เราได้รับอนุญาตให้ใช้ตัวคั่นใด ๆ ฉันจะใช้ zz เป็นตัวคั่น ดังนั้นการนับตั้งแต่ 1 ถึง (แต่ไม่รวม) 10 ในขั้นตอนที่ 3 จะถูกป้อนเป็น:

1zz<zz10zz3

โปรแกรมใหม่ซึ่งมีอินพุตที่คั่นด้วย zz คือ

dc (48 ไบต์):

1sb[_1sb]sz?sdiilb*sci[pld+lnx]sl[dlb*lcr<l]dsnx

นี่คือหนึ่งไบต์ยาวกว่าโซลูชันแรก 47 ไบต์

ลองใช้เวอร์ชันที่คั่นด้วย zz ออนไลน์!

โดยส่วนตัวแล้วฉันคิดว่าการ< 1 10 3จัดรูปแบบคำสั่งซื้อที่แตกต่างนั้นมีความสำคัญกับปัญหามากขึ้น แต่อาจ1zz<zz10zz3ตรงกับข้อกำหนดทางเทคนิคที่เกิดขึ้นจริง

คุณอาจจะได้คำตอบที่สั้นกว่านี้หากคุณอนุญาตให้ตัวคั่นที่แตกต่างกันระหว่างอาร์กิวเมนต์อินพุตที่ต่างกัน แต่ฉันไม่คิดว่านั่นเป็นจิตวิญญาณของปัญหา

ยูทิลิตีBash + Unix ขนาด 29 ไบต์

คุณสามารถเปลี่ยนแนวคิดพื้นฐานข้างต้นเป็นโปรแกรมทุบตี (ซึ่งเรียก dc); สิ่งนี้จะหลีกเลี่ยงปัญหาทั้งหมดที่มี "<" และ ">" และยังช่วยให้การจัดการพารามิเตอร์ตัวเลขต่าง ๆ ได้ง่ายขึ้นดังนั้นจึงมีความยาวเพียง 29 ไบต์เช่นเดียวกับ @ zeppelin's bash + bc answer

รุ่นทุบตี (29 ไบต์):

dc -e[p$4+d$3r$2l]sl$1d$3r$2l

ลองใช้เวอร์ชั่นทุบตีออนไลน์!

นี่คือคำอธิบายว่าโปรแกรม dc ภายในโปรแกรม bash ทำงานอย่างไร:

ค่าของ i ถูกเก็บไว้ที่ด้านบนสุดของสแต็กเกือบตลอดเวลา

[      Start of macro (i is at the top of the stack). This macro will be called l.
p      Print i
$4+    i += (4th argument)
d      Duplicate i at the top of the stack.
$3     Push the 3rd argument onto the stack.
r      Swap the top two items on the stack, so i is at the top and arg3 is second
$2l    $2 is "<" or ">", causing the top two items to be popped from the stack, and macro l is then called (effectively looping back) if i < arg3 or i > arg3, respectively.
]sl    End of macro definition; store macro in register l.

$1     Push argument 1 onto the stack (i = 1st argument).
d$3r$2l Just as above, call macro l if i < arg3, or i > arg3, depending on whether arg2 is "<" or ">"

3

เสียงกระเพื่อมสามัญ 82 80 79 73 64 ไบต์

(defmacro f(a b c d)`(do((i,a(+ i,d)))((not(,b i,c)))(print i)))

ทดสอบ

(f 1 < 10 1)

1 
2 
3 
4 
5 
6 
7 
8 
9 
NIL
CL-USER> 

-9 ไบต์ขอบคุณPrzemysławP


บางทีคุณสามารถบันทึก 9 ไบต์โดยกำหนดแมโคร (defmacro f(a b c d)<insert backqoute here>(do((i,a(+ i,d)))((not(,b i,c)))(print i)))การใช้งาน:(f 1 < 10 1)

@ PrzemysławPขอบคุณอีกครั้ง!
coredump

3

PHP, 69 65 ไบต์

for(list(,$i,$b,$c,$d)=$argv);$b<"="?$i<$c:$i>$c;$i+=$d)echo"$i
";

ทำงานด้วย '-r'; จัดเตรียมอาร์กิวเมนต์บรรทัดคำสั่งเป็นอินพุต

สำหรับหนึ่งไบต์เพิ่มอีก 4 ไบต์ฉันสามารถใช้ตัวดำเนินการทุกอันได้:

for(list(,$i,$b,$c,$d)=$argv;eval("return $i$b$c;");$i+=$d)echo"$i
";

ใช่มันชั่วร้าย คุณรู้หรือไม่ว่ามันสามารถคืนบางสิ่งได้?


การทำลายแบบชวเลข[,$i,$b,$c,$d]=$argv;จะช่วยประหยัดได้อีก 4 ไบต์
แต่ PHP 7.1 โพสต์ความท้าทาย


เรียบร้อยแล้ว! ฉันไม่แน่ใจเมื่อสร้างความท้าทายถ้าฉันควรรวมตัวดำเนินการทั่วไปทุกตัวฉันจำได้ว่าพวกเขาไม่เหมือนกันทั้งหมด (~ = สำหรับ! = ในตัวอย่างของ Lua)
Sygmei

ว้าวความชั่วร้ายก็คือความชั่วร้าย
cyberbit

ฉันว่าคุณสามารถใช้ PHP 7.1 เพื่อทำให้สั้นลง หากไม่เป็นเช่นนั้นการใช้การlistบันทึก 4 ไบต์บวก 4 ไบต์ที่มีไวยากรณ์แบบสั้น
JörgHülsermann

@PHP 7.1 โพสต์ความท้าทาย; list()แต่ขอบคุณสำหรับ
ติตัส

2

Perl 6 , 44 ไบต์

{.say for $^a,*+$^d...^*cmp$^c!= $^b.ord-61}

มันทำงานอย่างไร

{                                          }  # A lambda.
          $^a                                 # Argument a.
             ,*+$^d                           # Iteratively add d,
                   ...^                       # until (but not including the endpoint)
                       *cmp$^c                # the current value compared to c
                                              # (less=-1, same=0, more=1)
                              != $^b.ord-61.  # isn't the codepoint of the b minus 61.
 .say for                                     # Print each number followed by a newline.

หากไม่สามารถส่งคืนลำดับ (อาจเป็นอนันต์) ของตัวเลขเป็นค่าประเภทSeqแทนที่จะพิมพ์ตัวเลขไปยัง stdout ชิ้น.say forส่วนนั้นจะถูกลบออกซึ่งจะนำไปสู่ ​​35 ไบต์


2

Clojure 66 66ไบต์

#(when((if(= %2"<")< >)% %3)(println %)(recur(+ % %4)%2 %3 %4))

-3 loopไบต์โดยแฟออก ฉัน "เหยียดหยาม" พารามิเตอร์ init เพื่อทำหน้าที่เป็นตัวสะสมการทำงาน

โซลูชันแบบเรียกซ้ำ (ด้วย TCO) ดูความคิดเห็นในรหัส pregolfed ฉันลองใช้โซลูชันแบบเรียกซ้ำที่ไม่ใช่ TCO และสิ้นสุดที่ 67 ไบต์

ฉันชอบที่จะเห็นจังหวะนี้ใน Clojure! ฉันคิดว่านี่เป็นสิ่งที่เล็กที่สุดที่ฉันจะได้รับ

(defn my-for [init-num com-str com-num inc-num]
  (let [op (if (= com-str "<") < >)] ; Figure out which operator to use
    (when (op init-num com-num) ; When the condition is true, print and recur
      (println init-num)
      (recur (+ init-num inc-num) com-str com-num inc-num))))
    ; Else, terminate (implicit) 

โอ้ฉันไม่ได้สังเกตคำตอบนี้ #(when(({">">"<"<}%2)% %3)(println %)(recur(+ % %4)%2 %3 %4))จะเป็น 61 ไบต์รวมwhenกับของ({">">"<"<}%2)คุณ
NikoNyrh

2

Groovy ขนาด 51 ไบต์

{a,b,c,d->while(Eval.me("$a$b$c")){println a;a+=d}}

นี่คือการปิดไม่มีชื่อ ลองออนไลน์!

ข้อควรระวัง - หากคุณต้องการทดสอบสิ่งนี้ด้วยgroovy consoleตรวจสอบให้แน่ใจว่าคุณได้ฆ่ากระบวนการทั้งหมดเมื่ออินพุตทำให้เกิดการวนซ้ำไม่สิ้นสุด ฉันสังเกตุสิ่งนี้หลังจากกิน RAM ได้ประมาณ 5 กิ๊ก


2

QBIC , 51 40 ไบต์

:;::{?a┘a=a+c~A=@<`|~a>=b|_X]\~a<=b|_X

และสามนาทีหลังจากโพสต์ฉันรู้ว่าฉันสามารถลดความซับซ้อนของตรรกะเทอร์มินัล ...

:;::      Consecutively read a, A$, b and c from the command line
{?a┘      Start an infinite loop; print a, add a newline to the source
a=a+c     increment a
~A=@<`|   If we are in LESS THAN mode
  ~a>=b   and IF we are no longer LESS
    |_X]  THEN QUIT, end if.
  \       ELSE (we're in GREATER THAN mode)
    ~a<=b IF we are no longer GREATER
    |_X   THEN QUIT
          The last IF and the loop are auto-closed

2

แบตช์ 94 ไบต์

@set i=%1
@set o=gtr
@if "%~2"=="<" set o=lss
:g
@if %i% %o% %3 echo %i%&set/ai+=%4&goto g

หากไม่ใช่สำหรับการทำงานของพารามิเตอร์ตัวที่สองก็สามารถทำได้ใน 53 ไบต์:

@for /l %%i in (%1,%4,%n%)do @if not %%i==%3 echo %%i

สิ่งนี้จะไม่ทำอะไรเลยหากขั้นตอนนั้นมีเครื่องหมายผิด การทดสอบพิเศษเนื่องจากการforวนซ้ำของแบทช์อนุญาตให้ตัวแปรลูปเท่ากับค่าสิ้นสุด


2

Clojure 66 ไบต์

#(loop[i %](if(({">">"<"<}%2)i %3)(do(println i)(recur(+ i %4)))))

สิ่งนี้อาจมีขนาด 55 ไบต์<และ>เป็นฟังก์ชันใน Clojure:

(def f #(loop[i %](if(%2 i %3)(do(println i)(recur(+ i %4))))))
(f 1 < 10 1)

ฉันชอบการใช้แผนที่ที่นี่ ฉันไม่เคยคิดเลยว่ามันจะทำให้ฉันพ่ายแพ้ สิ่งที่น่าสนใจอีกอย่างคือการนับครั้งแรกของเราเหมือนกันแม้จะมีวิธีการที่แตกต่างกันเล็กน้อย
Carcigenicate

ช่วยให้ขจะเป็นฟังก์ชั่นที่จะให้ข้อได้เปรียบที่ไม่เป็นธรรมบางภาษา :)
Sygmei

จริง แต่ผมคิดว่าภาษาส่วนใหญ่ฉันรู้ว่าจะไม่ได้รับประโยชน์มากจากการอนุญาตให้<แทนการ"<"ยกเว้น Clojure
NikoNyrh

@Sygmei True มันจะหวานประหลาดแม้ว่า ไม่สามารถตำหนิคุณโทรได้
Carcigenicate

OP กล่าวว่าตัวอักษรนั้นใช้ได้ดีแทนที่จะเป็นสตริงสำหรับตัวดำเนินการเปรียบเทียบ btw ที่ควรบันทึกสองสามไบต์
Carcigenicate
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.