กล่องดนตรี 4-note ของฉันสามารถเล่นเพลงนั้นได้หรือไม่?


51

ฉันมีกล่องดนตรีที่หมุนได้ซึ่งสามารถเล่นโน้ตสี่ชุดได้ เมื่อฉันหมุนข้อเหวี่ยงมันจะดึงหนึ่งในสี่สายขึ้นอยู่กับตำแหน่งของข้อเหวี่ยงและทิศทางของการเลี้ยว เมื่อข้อเหวี่ยงหมุนไปทางเหนือกล่อง (ที่มีหมายเลขกำกับตั้งแต่ 1 ถึง 4) จะเป็นดังนี้:

1  |  2
   |
   O   

4     3

จากตรงนั้นฉันสามารถหมุนข้อเหวี่ยงตามเข็มนาฬิกาเพื่อถอนสาย # 2 และชี้จุดหมุนตะวันออก:

1     2

   O---   

4     3

หรือฉันอาจหมุนทวนเข็มนาฬิกาจากทิศเหนือเพื่อเล่นสตริง # 1 และจบลงด้วยข้อเหวี่ยงชี้ไปทางทิศตะวันตก:

1     2

---O   

4     3

เมื่อถึงเวลาใดก็ตามกล่องสามารถเล่นหนึ่งในสองโน้ต: โน้ตถัดไปที่มีในทิศทางตามเข็มนาฬิกาหรือโน้ตถัดไปในทิศทางทวนเข็มนาฬิกา

ท้าทาย

ความท้าทายของคุณคือการเขียนโปรแกรมหรือฟังก์ชั่นที่ยอมรับสตริงโน้ตที่ไม่ว่างเปล่า (เช่นตัวเลข1ผ่าน4) และพิจารณาว่าเป็นไปได้หรือไม่ที่จะเล่นลำดับของโน้ตบนกล่องดนตรี สร้างผลลัพธ์ที่เป็นจริงหรือเป็นเท็จเพื่อระบุความสามารถในการเล่นหรือไม่สามารถเล่นได้ของอินพุต

หมายเหตุบางส่วน:

  • อินพุตไม่มีข้อสันนิษฐานเกี่ยวกับตำแหน่งเริ่มต้น อินพุต214(เริ่มต้นทางทิศตะวันออกและเคลื่อนไหวทวนเข็มนาฬิกาอย่างเคร่งครัด) และ234(เริ่มต้นทางทิศเหนือและเคลื่อนไหวตามเข็มนาฬิกาอย่างเคร่งครัด) และใช้ได้ทั้งคู่

  • ข้อเหวี่ยงอาจเคลื่อนที่อย่างอิสระในทิศทางใดทิศทางหนึ่งหลังจากแต่ละโน้ต ชุดของบันทึกย่อเดียวกันเป็นไปได้ (เช่น, 33333) โดยการย้ายไปมาผ่านหนึ่งสาย ซีรีย์1221441สามารถเล่นได้อย่างสมบูรณ์แบบ (เริ่มต้นทางทิศตะวันตกย้ายตามเข็มนาฬิกาสองขั้นตอนแล้วทวนเข็มนาฬิกาสามขั้นตอนจากนั้นตามเข็มนาฬิกาสองขั้นตอน)

ตัวอย่าง

บางtrueกรณี:

1
1234
1221
3333
143332
22234
2234
22214
1221441
41233

บางfalseกรณี:

13     (note 3 is never available after note 1)
1224   (after `122`, the crank must be north, so 4 is not playable)
121    (after `12` the crank is east; 1 is not playable)
12221  (as above, after `1222` the crank is east)
43221  

อินพุตสามารถเป็นสตริงที่มีเครื่องหมายคำพูดได้หรือไม่?
Luis Mendo

@ LuisMendo แน่นอนว่าฉันจะอนุญาต - ฉันสนใจในอัลกอริทึมของคุณไม่ใช่การทำให้คุณผ่านการวนลูปเพื่อรับอินพุต อย่างไรก็ตามมีฉันทามติของชุมชนที่ไม่เป็นทางการว่าเป็นเรื่องปกติ: อินพุตสตริงที่มีหรือไม่มี“”
apsillers

1
ฉันไม่รู้ ขอบคุณสำหรับลิงค์!
Luis Mendo

1
@AJMansfield ไม่โซลูชั่นควรอนุญาตให้มีหลายรอบโดยพลการ แน่นอนถ้าการป้อนข้อมูลบางอย่างทำให้รหัสของคุณเกินขีด จำกัด ในล่ามภาษาของคุณหรือหน่วยความจำของคอมพิวเตอร์ของคุณนั่นก็ดี (เนื่องจากมันถูก จำกัด ด้วยหน่วยความจำที่คุณมีหรือล่ามของคุณอนุญาต) แต่วิธีการแก้ปัญหาของคุณ หรือว่ามีการเคลื่อนที่ของข้อเหวี่ยงกี่ครั้ง
apsillers

1
ความท้าทายนี้ได้รับรางวัลไม่ง่ายอย่างที่คิดไว้ในหมวด Best of PPCG 2016 แต่น่าเสียดายที่เราไม่สามารถมอบรางวัลให้กับความท้าทายได้แต่ Zgarb เขียนความท้าทายเพื่อเป็นเกียรติแก่คุณ ขอแสดงความยินดี!
Martin Ender

คำตอบ:


9

Pyth, 30 27 ไบต์

f!-aVJ.u%-ysYN8zTtJ,1 7cR2T

นี่คือแนวคิด:

 1.5  1  0.5

  2       0

 2.5  3  3.5

ข้อเหวี่ยงอยู่ในตำแหน่งครึ่งจำนวนเต็มcเสมอ ในแต่ละขั้นตอนเราสะท้อนให้เห็นมันมากกว่าบันทึกตำแหน่งจำนวนเต็มโดยการตั้งค่าn c = 2*n-cหากnถูกต้องการcเปลี่ยนแปลงโดย± 1 mod 8 หากnไม่ถูกต้องการcเปลี่ยนแปลงโดย± 3 mod 8 เราจะลดการสะสมของอินพุตเพื่อรวบรวมค่าทั้งหมดcและจากนั้นดูว่าบันทึกทั้งหมดนั้นถูกต้องหรือไม่ เราทำสิ่งนี้สำหรับค่าเริ่มต้นทุกตัวcเพราะมันสั้นกว่าการตรวจสอบค่าที่อยู่ติดกับหมายเหตุแรก

จัดรูปแบบ:

f
  ! -
      aV J .u
              % -
                  y s Y
                  N
                8
              z
              T
         t J
      ,
        1 
        7
  cR2 T

ชุดทดสอบ


18

CJam, 34 31 ไบต์

8,q{~2*f{_@-_zF8b&,@@+8,=*}0-}/

ทำสิ่งนี้ในโทรศัพท์ของฉันดังนั้นฉันจะต้องอธิบายเพิ่มเติมในภายหลัง เอาท์พุทไม่ว่างเปล่าถ้าเป็นจริง

ลองใช้ออนไลน์ | ชุดทดสอบ

คำอธิบาย

รหัสใหม่เลื่อนเค้าโครงเล็กน้อย:

2    3    4

1    .    5

0/8  7    6

แม้ตัวเลขจะสอดคล้องกับตำแหน่งสตริงและตัวเลขคี่จะตรงกับตำแหน่งข้อเหวี่ยง

นี่คือสิ่งที่เกิดขึ้น:

8,           Create the range [0 1 .. 7] of possible starting positions
             We can leave the string positions [0 2 4 6] in since it doesn't matter
q{ ... }/    For each character in the input...
  ~2*          Evaluate as integer and double, mapping "1234" -> [2 4 6 8]
  f{ ... }     Map over our possible current crank positions with the string
               position as an extra parameter
    _@-          Calculate (string - crank), giving some number in [-7 ... 7]
    _z           Duplicate and absolute value
    F8b          Push 15 base 8, or [1 7]
    &,           Setwise intersection and get length. If (string - crank) was in
                 [-7 -1 1 7] then the move was valid and this evaluates to 1, otherwise 0
    @@+          Calculate ((string - crank) + string)
    8,=          Take modulo 8, giving the new crank position. x%y in Java matches the
                 sign of x, so we need to do ,= (range + index) to get a number in [0 .. 7]
    *            Multiply the new crank position by our previous 0 or 1
  0-           Remove all 0s, which correspond to invalid positions

สแต็กจะถูกพิมพ์โดยอัตโนมัติในตอนท้าย ตำแหน่งสิ้นสุดที่เป็นไปได้ใด ๆ จะอยู่ในเอาต์พุตเช่นสำหรับอินพุต1เอาต์พุตคือ31ซึ่งหมายความว่าข้อเหวี่ยงสามารถหันหน้าไปทางซ้ายหรือขึ้น

หากมีเพียง CJam เท่านั้นที่มีตัวกรองพร้อมพารามิเตอร์เพิ่มเติม ...


แก้ไข: ย้อนกลับชั่วคราวขณะที่ฉันโน้มน้าวตัวเองว่า 29- ไบต์นี้ทำงาน:

8,q{~2*f{_@-_7b1#@@+8,=|}W-}/

37
ทุกครั้งที่มีคนตอบด้วยภาษายาก ๆ เช่น cjam และพูดว่า "ทำสิ่งนี้ทางโทรศัพท์ของฉัน" ฉันตายไปข้างในนิดหน่อย
Dennis van Gils

2
เขาอาจหมายถึงข้อความที่ส่งออกโดยใช้โทรศัพท์ แต่มันทำในหัวของเขา
เนลสัน

7

Haskell, 93 88 87 ไบต์

any(all(\(a,b:c)->1>mod(a!!1-b)4).(zip=<<tail)).mapM((\a->[[a,a+1],[a+1,a]]).read.pure)

สิ่งนี้ประเมินว่าเป็นฟังก์ชันที่ไม่ระบุตัวตนซึ่งรับสตริงและส่งคืนบูลีน ชุดทดสอบที่นี่

คำอธิบาย

แนวคิดก็คือแลมบ์ดาทางด้านขวาจะจับคู่ตัวเลขaกับ[[a,a+1],[a+1,a]]"การเคลื่อนไหว" ที่เป็นไปได้ทั้งสองที่จะนำข้อเหวี่ยงไปที่หมายเลขนั้นตามแผนภาพต่อไปนี้:

  1 (2) 2

(1/5)  (3)

  4 (4) 3

ในฟังก์ชั่นหลักที่ไม่เปิดเผยตัวตนเราทำครั้งแรกmapM((...).read.pure)ซึ่งแปลงอักขระแต่ละตัวเป็นจำนวนเต็มใช้แลมบ์ดาด้านบนและเลือกหนึ่งในสองการเคลื่อนไหวแล้วส่งกลับรายการลำดับการย้ายที่เกิดขึ้นทั้งหมด จากนั้นเราตรวจสอบว่าลำดับใด ๆ เหล่านี้มีคุณสมบัติที่จำนวนที่สองของการย้ายแต่ละครั้งเท่ากับจำนวนแรกของโมดูโล 4 ถัดไปซึ่งหมายความว่ามันเป็นลำดับทางกายภาพที่เป็นไปได้ การทำเช่นนี้เราzipแต่ละลำดับย้ายด้วยtail, ตรวจสอบสภาพสำหรับallคู่และดูว่าลำดับการประเมินanyTrue



6

เรติน่า127 127ไบต์

^((1|2)|(2|3)|(3|4)|(4|1))((?<2-5>1)|(?<5-2>1)|(?<3-2>2)|(?<2-3>2)|(?<4-3>3)|(?<3-4>3)|(?<5-4>4)|(?<4-5>4))*$

พิมพ์นี้0หรือ1ตาม

ลองออนไลน์! (นี่เป็นรุ่นที่แก้ไขเล็กน้อยซึ่งทำเครื่องหมายการแข่งขันทั้งหมดในอินพุตแทนการพิมพ์0หรือ1.)

ฉันลองใช้อัลกอริธึมที่สวยงาม แต่ความพยายามครั้งแรกของฉันไม่สามารถหลีกเลี่ยงการย้อนรอยกลับได้ ... และการนำการย้อนรอยกลับมาใช้นั้นน่ารำคาญมาก ... ดังนั้นฉันจึงใช้ภาษาที่ทำย้อนรอยให้ฉัน ทางออกที่ถูกต้อง น่าเสียดายที่การเข้ารหัสนั้นค่อนข้างละเอียดและซ้ำซ้อนอย่างมาก ... ฉันแน่ใจว่านี่จะสั้นลง

ในขณะที่ฉันพยายามคิดอะไรบางอย่างที่ neater ถ้าใครอยากรู้ว่ามันทำงานอย่างไรนี่เป็นรุ่นที่อ่านง่ายกว่า:

^
(
    (?<a>1|2)
  | (?<b>2|3)
  | (?<c>3|4)
  | (?<d>4|1)
)
(
    (?<a-d>1) | (?<d-a>1)
  | (?<b-a>2) | (?<a-b>2)
  | (?<c-b>3) | (?<b-c>3)
  | (?<d-c>4) | (?<c-d>4)
)*
$

และนี่คือคำใบ้:

1  a  2

d  O  b

4  c  3

6

MATL , 57 55 ไบต์

1t_hjnZ^!t1tL3$)2_/wvG1)UGnl2$Ov+Ys.5tv3X53$Y+4X\G!U=Aa

สิ่งนี้ใช้รีลีสปัจจุบัน (10.2.1)ซึ่งเร็วกว่าความท้าทายนี้

แก้ไข (17 มกราคม 2017): เนื่องจากการเปลี่ยนแปลงในภาษาvจำเป็นต้องถูกแทนที่ด้วย&vและtL3$)โดยY)(นอกจากนี้ยังสามารถทำการปรับปรุงอื่น ๆได้) ลิงค์ต่อไปนี้มีการแก้ไขสองรายการ

ลองออนไลน์!

คำอธิบาย

นี้จะขึ้นอยู่กับสองของเครื่องมือที่ชื่นชอบสำหรับการเล่นกอล์ฟรหัส: กำลังดุร้ายและบิด

รหัสกำหนดเส้นทางตามข้อเหวี่ยงในแง่ของพิกัด0.5, 1.5ฯลฯ ตัวเลขแต่ละตัวบอกตำแหน่งของข้อเหวี่ยงระหว่างโน้ต รหัสแรกจะสร้างอาร์เรย์พา ธด้วยเส้นทางที่เป็นไปได้ทั้งหมดที่เริ่มต้นด้วยหมายเหตุแรกของสตริงป้อนเข้า แต่ละพา ธ คือคอลัมน์ในอาร์เรย์นี้ นี่คือองค์ประกอบกำลังดุร้าย

จากอาร์เรย์พา ธ นี้จะได้รับอาร์เรย์โน้ตซึ่งแต่ละคอลัมน์เป็นลำดับของบันทึกย่อที่เล่นได้ ยกตัวอย่างเช่นการเคลื่อนไหวจากตำแหน่ง0.5เพื่อผลิตโน้ต1.5 1สิ่งนี้ประกอบด้วยการหาค่าเฉลี่ยระหว่างตำแหน่งและจากนั้นใช้การดำเนินการแบบโมดูโล 4 เฉลี่ยวิ่งไปตามแต่ละคอลัมน์จะทำกับ 2D บิด

สุดท้ายโปรแกรมจะตรวจสอบว่าคอลัมน์ใด ๆ ของแถวลำดับทราบตรงกับอินพุตหรือไม่

1t_h        % row array [1, -1]
j           % input string
nZ^!        % Cartesian power of [1, -1] raised to N, where "N" is length of string
t           % duplicate
1tL3$)      % extract first row
2_/         % divide by -2
wv          % attach that modified row to the top of Cartesian power array
G1)U        % first character of input string converted to number, "x"
Gnl2$O      % column array of N-1 zeros, where N is length of input
v           % concat vertically into column array [x;0;0...;0]
+           % add with singleton expansion
Ys          % cumulative sum along each column. Each column if this array is a path
.5tv        % column array [.5;.5]
3X5         % predefined string 'same' (for convolution)
3$Y+        % 2D convolution of path array with [.5;.5]
4X\         % modified modulo operation. This gives note array with values 1,2,3,4
G!U         % column array of input string characters converted to numbers
=Aa         % true if any column of the note array equals this

5

Pyth, 43

Km-R2sMdc`M%R4-VJjQTtJ`0|Fm!s-VKdCm_B^_1dlK

ชุดทดสอบ

อาจเป็นเรื่องที่เล่นได้ง่ายและไม่ใช่อัลกอริธึมที่เหมาะสมที่สุดสำหรับการเล่นกอล์ฟ (ฉันคาดหวังว่าการแจกแจงเส้นทางทั้งหมดจะสั้นลงหรือไม่) ... อย่างไรก็ตามถ้าคุณพบข้อผิดพลาดใด ๆ กับอัลกอริทึมโปรดแจ้งให้เราทราบ เคยผิดพลาดมาก่อน!

1221ฉันจะอธิบายขั้นตอนวิธีของฉันโดยใช้การป้อนข้อมูลตัวอย่างของ [[1,2],[2,2],[2,1]]โปรแกรมนี้เป็นครั้งแรกแผนที่ตัวเลขกับผู้สืบทอดของพวกเขาเช่นดังนั้น: จากนั้นก็จะได้รับความแตกต่างของพวกเขา mod 4(Pyth ได้รับผลที่ตรงกับสัญลักษณ์ของการโต้แย้งทางขวาของดังนั้นนี้เป็นบวกเสมอ):% [3,0,1]จากนั้นผลลัพธ์จะถูกแยกออก0และ2หักลบออกจากแต่ละรายการ: [[1],[-1]].

ตอนนี้การตั้งค่าเสร็จสิ้นเราสร้างรายการ[-1,1,-1...]และการปฏิเสธของมัน[1,-1,...]ทั้งความยาวเท่ากับอาร์เรย์ผลลัพธ์จากก่อนหน้า จากนั้นสำหรับแต่ละรายการเหล่านี้ให้ทำการลบ setwise ระหว่างองค์ประกอบของรายการและรายการที่สร้างขึ้นในขั้นตอนก่อนหน้า จากนั้นหากผลลัพธ์ใดรายการหนึ่งมีเพียงรายการที่ว่างเปล่าเราจะแสดงผลเป็นจริง


คุณหมายความว่าอย่างไร "ผลลัพธ์ถูกแบ่งเป็น 0"? โดยเฉพาะอย่างยิ่งสิ่งที่คุณจะได้รับ1221221และ1221441?
Neil

1
@ Neil 1221221เป็นเท็จและ1221441ให้ภาพรวมที่แท้จริง แต่ถ้าฉันเข้าใจว่าคุณต้องการผลลัพธ์หลังจากขั้นตอนนั้นในอัลกอริทึมหรือไม่ หากเป็นกรณีที่จะช่วยให้การศึกษา: จาก[3, 0, 1, 3, 0, 1]ไป[[3], [1, 3], [1]]และจะ[3, 0, 1, 1, 0, 3] [[3], [1, 1], [3]]แจ้งให้เราทราบหากคุณต้องการคำอธิบายอย่างอื่น :)
FryAmTheEggman

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

1
@Neil แน่นอนว่าไม่มีปัญหา :) จากนั้นเราทำการลบเพื่อรับ: [[1], [-1, 1], [-1]]และ[[1], [-1, -1], [1]]จากที่นี่คุณจะเห็นว่ารายการแรกไม่มีรายการที่สลับกันระหว่าง-1และ1ในขณะที่รายการอื่นทำเพื่อให้ได้ผลลัพธ์สุดท้าย อัลกอริทึมเป็นบิตป้าน แต่โดยทั่วไปแล้วการทำแผนที่การเปลี่ยนแปลง0ทิศทางและทิศทางเป็น+/-1แล้วตรวจสอบว่าไม่มีการกระโดดและทิศทางทำให้รู้สึก
FryAmTheEggman

โอ้ดังนั้นสิ่งที่ฉันขาดหายไปก็คือแต่ละรายการแยกจะต้องประกอบด้วยค่าเดียวกันและค่าเหล่านั้นต้องสลับกัน ขอบคุณ!
Neil

4

Matlab, 279 180 ไบต์

o=eye(4);a=input('')-'0';M=[o,o(:,[4,1:3]);o(:,[2:4,1:4,1])];x=2;for p=[a(1),mod(a(1),4)+1];for k=a;i=find(M*[o(:,k);o(:,p)]>1);if i;p=mod(i-1,4)+1;else;x=x-1;break;end;end;end;x>0

วิธีแก้ปัญหาที่ค่อนข้างขี้เกียจ แต่สิ่งที่สั้นที่สุดที่ฉันสามารถทำได้คือ ฉันสร้างเมทริกซ์พิเศษ: เมื่อคุณเข้ารหัสสถานะของ plucker และสตริงสุดท้ายที่จะถูกดึงมันจะส่งคืนเวกเตอร์ที่เข้ารหัสตำแหน่งใหม่ของ plucker และไม่ว่าจะถอนก่อนหน้านี้ได้หรือไม่ ตอนนี้เราแค่วนรอบโน้ตทั้งหมดจากตำแหน่งเริ่มต้นที่เป็นไปได้ทั้งสองและดูว่าหนึ่งในนั้นส่งผลให้เกิดท่วงทำนองที่เล่นได้หรือไม่ อาจจะสามารถเล่นกอล์ฟได้มากขึ้น

ที่ขยายและอธิบายแหล่งที่มา:

o=eye(4);
a=input('')-'0';

% encoding of plucker/notes
%      1
%   1     2
%4           2
%   4     3
%      3
%

M=[...
%12 3 4 1 2 3 4 <
1,0,0,0,0,1,0,0; %1  k = current note
0,1,0,0,0,0,1,0; %2  
0,0,1,0,0,0,0,1; %3  
0,0,0,1,1,0,0,0; %4  
0,0,0,1,0,0,0,1; %1  p = current position of plucker
1,0,0,0,1,0,0,0; %2
0,1,0,0,0,1,0,0; %3
0,0,1,0,0,0,1,0];%4
% the vector we multiply with this matrix has following structure,
% the k-th and the p+4 th entries are 1, the rest 0
% when we multiply this vecotr with this matrix, we get a vector with an
% entry of value 2 IF this is a valid move ( mod(positionOfThe2 -1,4)+1 is
% the position of the plucker now)
% or only entries less than 2 it is impossible
x=2;  %number of "chances" to get it right
for p=[a(1),mod(a(1),4)+1] %check both starting values;
    for k=a;                %loop throu the notes
        size(M);

        c = M * [o(:,k);o(:,p)];
        i=find(c>1);               %did we find a 2?
        if i;
           p=mod(i-1,4)+1;         %if yes, valid move
        else;
            x=x-1;                 %if no, invalid, 
            break;
        end 
    end
end
x=x>0 %if we failed more than once, it is not possible

4

ES6, 104 100 ไบต์

s=>!/13|24|31|42|3[24]{2}1|4[13]{2}2|1[24]{2}3|2[13]{2}4|(.).\1/.test(s.replace(/(.)(\1\1)+/g,"$1"))

แก้ไข: บันทึกแล้ว 4 ไบต์ด้วย @DigitalTrauma

นี่คือการเขียนใหม่ทั้งหมดเนื่องจากวิธีการก่อนหน้าของฉันมีข้อบกพร่อง

ฉันเริ่มต้นด้วยการลดจำนวนการวิ่งทั้งหมดเป็น 1 หรือ 2 ขึ้นอยู่กับว่ามีเลขคี่หรือเลขคู่ในการวิ่ง จากนั้นฉันจะมองหาชุดค่าผสมที่ผิดกฎหมายทั้งหมด:

  • 13|24|31|42 (ฝั่งตรงข้าม)
  • 3[24]{2}1เป็น3221และ3441ผิดกฎหมาย
  • ในทำนองเดียวกันสำหรับ4xx2, 1xx3และ2xx4ที่xเป็นทั้งของตัวเลขที่ขาดหายไป
  • (.).\1เป็นสิ่งที่ชอบ121ที่ผิดกฎหมาย ( 111ได้รับการลดลงไป1ก่อนหน้านี้)

หากไม่มีคู่ที่ผิดกฎหมายหรือ "triples" สตริงทั้งหมดนั้นถูกต้องตามกฎหมาย (การพิสูจน์โดยการเหนี่ยวนำจะถูกทิ้งไว้เป็นแบบฝึกหัดเพราะมันเป็นช่วงดึกที่นี่)

ฉันพยายามทำให้ง่ายขึ้น3[24]{2}1|1[24]{2}3โดยใช้การยืนยันเชิงลบ lookahead แต่มันกลับกลายเป็นว่านานกว่านั้น


f("1122") => true@DigitalTrauma
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴฉันเห็นว่าไม่มีอะไรผิดปกติ ในทางกลับกันฉันก็รู้ว่าf("1221221")คำตอบนั้นผิดดังนั้นฉันจะต้องคิดใหม่
Neil

เป็นเรื่องที่ดีที่จะรวมชุดทดสอบไว้ '43221' ล้มเหลว: jsbin.com/vafitotequ/1/edit?js,console
Pavlo

@Pavlo อ๊ะผมแข็งแรงเล่นกอล์ฟ[24][24]ไป(2|4)\1แต่ผมไม่ได้ผ่านการทดสอบอย่างเพียงพอ ขอโทษสำหรับเรื่องนั้น.
Neil

คุณสามารถกอล์ฟ[24][24]เพื่อ[24]{2}?
Digital Trauma

2

JavaScript (ES6), 80 ไบต์

s=>[r=0,1,2,3].map(i=>[...s].map(n=>n-1-i%4?n%4-i%4?v=0:i+=3:i++,v=1)|v?r=1:0)|r

คำอธิบาย

i%4 เป็นตำแหน่งข้อเหวี่ยงปัจจุบัน:

    1 (i%4 == 1) 2   

(i%4 == 0) (i%4 == 2)

    4 (i%4 == 3) 3   

เยื้องและแสดงความคิดเห็น

s=>
  [r=0,1,2,3].map(i=> // i = crank position, test for i starting at 0 to 3, r = result
    [...s].map(n=>    // for each note n
      n-1-i%4?        // if n is not at the position after i
        n%4-i%4?      // if n is not at the position before i
          v=0         // set the result of this test to invalid
        :i+=3         // else i-- (+3 used because i%4 would break for negative values)
      :i++,           // else i++
      v=1             // v = result of test, initialise to 1 (valid)
    )
    |v?r=1:0          // if the test returned true, set the result to true
  )
  |r                  // return the result

ทดสอบ

var solution = s=>[r=0,1,2,3].map(i=>[...s].map(n=>n-1-i%4?n%4-i%4?v=0:i+=3:i++,v=1)|v?r=1:0)|r
<input type="text" value="1221441" oninput="result.textContent=solution(this.value)" />
<pre id="result"></pre>


ทำได้ดีมาก คุณจะอธิบายวิธีการ|ทำงานในกรณีนี้หรือไม่?
Pavlo

1
@pavlo ขอบคุณ (x.map(...),v)มันเป็นวิธีที่สั้นของการเขียน มันทำงานได้เพราะอาร์เรย์ว่าmapผลตอบแทนที่ได้ปลดเปลื้องไปและ0 0|v == v
user81655

2

Lua , 146 142 108 162 159 149 144 135 132 118 113 ไบต์

z,q,s=0,0,io.read()for i in s:gmatch'.'do t=i-z if 2==math.abs(t)or t==q then return''end q=-t z=i end return 2>1

ส่งคืนค่าจริงหรือเท็จโดยกำหนดสตริงตัวเลขระหว่าง 1 ถึง 4 (ไม่ได้จัดการกับข้อมูลหรือหมายเลขนอกช่วง

เพียงแค่ติดตามว่าการเคลื่อนไหวครั้งสุดท้ายเป็นอย่างไรและตรวจสอบว่าการเคลื่อนไหวนี้เป็นการย้อนกลับของการเคลื่อนไหวครั้งสุดท้าย (IE, 121 หรือ 12221) หรือหากการเคลื่อนที่ระยะทางไกลเกินกว่าที่เป็นไปได้

แก้ไข 1 :

บันทึก 6 ไบต์ ฉันลืมไปแล้วว่าif (int) thenคืนค่าจริงถ้า int ไม่ใช่ศูนย์

ดังนั้น:

if t~=0 then

เปลี่ยนเป็น:

if t then

บันทึกสองสามไบต์ด้วยการจัดโครงสร้างใหม่

แก้ไข 2 :

ฉันคิดออกช้าๆ ฉันได้อ่านเอกสารที่นี่แล้ว: http://www.lua.org/pil/และหนึ่งในหน้าที่มีประโยชน์มากกว่าสำหรับการเล่นกอล์ฟคือhttp://www.lua.org/pil/3.3.html

โดยเฉพาะอย่างยิ่งสิ่งนี้มีประโยชน์มาก:

เช่นเดียวกับโครงสร้างการควบคุมตัวดำเนินการเชิงตรรกะทั้งหมดพิจารณาว่าเป็นเท็จและไม่มีเป็นเท็จและอะไรก็ได้ที่เป็นจริง

สิ่งนี้มีความหมายสำหรับฉันคือฉันสามารถไปข้างหน้าและลบการประกาศของฉันสำหรับ q ( ซึ่งถูกตั้งค่าเริ่มต้นเป็น 0 ) ตามที่มันจะถือเป็น "เท็จ" จนกว่าจะมีการตั้งค่า ดังนั้นฉันบันทึกอีกไม่กี่ไบต์ผ่านทางนี้

สิ่งที่ควรค่าแก่การพูดถึงถึงแม้ว่าฉันจะไม่ใช้มันคือถ้าคุณต้องการแลกเปลี่ยนค่าใน Lua คุณสามารถทำได้ a,b=b,aโดยไม่จำเป็นต้องใช้ตัวแปรชั่วคราว

แก้ไข 3

ดังนั้นผ่านการสร้างใหม่ที่ชาญฉลาดรวมถึงฟังก์ชั่นใหม่ฉันมีจำนวนไบต์เพิ่มขึ้นอีก 9 รายการ

โหมดที่ดีที่สุดสำหรับการรับอินพุต

หากคุณจำเป็นต้องอ่านในรายการตัวเลขและดำเนินการกับพวกเขาครั้งละหนึ่งรายการคุณสามารถใช้:

for x in string:gmatch('.') do
    print(x) --This is our number
end

เมื่อเปรียบเทียบกับทางเลือกของคุณโดยใช้ string: sub คุณสามารถเห็นค่าของกอล์ฟ (หรือการใช้งานทั่วไป):

for x=1,string:len() do
    print(string:sub(x,x)) --This is our number
end

ปรับโครงสร้างฟังก์ชั่นหรือสตริง

สิ่งที่สองหากคุณมีการประกาศหลายรายการในหนึ่งบรรทัดและหนึ่งในค่านั้นคือฟังก์ชันหรือคุณมีเงื่อนไขที่คุณจะเปรียบเทียบจำนวนกับผลลัพธ์ของฟังก์ชันดังนี้:

x,y,z=io.read(),0,0 print('test')

if math.abs(x)==2 then

โดยจัดโครงสร้างใหม่ดังนั้นวงเล็บปิดเป็นอักขระตัวสุดท้ายในเงื่อนไขหรือการประกาศคุณสามารถตัดตัวอักษรดังนี้:

y,z,x=0,0,io.read()print('test') --Notice no space

if 2==math.abs(x)then --If we put the '2' first in the conditional statement, we can now remove a space character

เงื่อนไขการคืนสินค้าที่เท่ากับจริงหรือเท็จแทน 'จริง' หรือ 'เท็จ'

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

ตัวอย่างเช่นเปรียบเทียบ:

return true
return false

ไปที่:

return 2>1
return 1>2

121ควรส่งออกเป็นเท็จ
lirtosiast

อาไม่เป็นไร ฉันเห็น. จะแก้ไขในไม่ช้า
Skyl3r

คุณอาจสนใจที่จะเพิ่มเคล็ดลับ Lua เหล่านั้นในTips สำหรับการเล่นกอล์ฟใน Luaหากคุณไม่เห็นพวกเขาอยู่ในรายการแล้ว
apsillers

2

MATL, 49 ไบต์ (ไม่แข่งขัน1 )

1. คำตอบ (ab) ใช้การจัดทำดัชนีที่เข้มงวดน้อยกว่าของ MATL เวอร์ชันใหม่กว่าและจะไม่ทำงานในเวลาที่มีการโพสต์ความท้าทายนี้

dt~aX`tt~f1)q:)w3MQJh)_ht~a]tT-3hX|n2=wT_3hX|n2=+

ลองออนไลน์! .

ฉันเห็นความท้าทายนี้ในงานBest of PPCG 2016และพบว่าสิ่งนี้สามารถใช้โอเปอเรเตอร์ที่ฉันชอบได้ :

d

หรือdiffใน MATLAB / Octave (ฉันจะใช้คำศัพท์ MATLAB / Octave อย่างอิสระในการอธิบายของฉันเพราะมันง่ายต่อการอ่านสำหรับมนุษย์) คำสั่งนี้คำนวณความแตกต่างที่ชาญฉลาดขององค์ประกอบในเวกเตอร์หรือในกรณีนี้ในอาร์เรย์ตัวละคร

สำหรับปัญหานี้ความแตกต่างมีรูปแบบที่น่าสนใจ สังเกตได้ว่า

การเปลี่ยนแปลงในทิศทางที่จะต้องหมายความว่าบันทึกการเล่นครั้งที่สอง

สำหรับรูปแบบที่แตกต่าง (ไม่สนใจการ1-4เปลี่ยนแปลงในตอนนี้) นี่หมายความว่า

การเปลี่ยนแปลงการลงชื่อเข้าใช้diff(input)จะต้องมีเลขศูนย์เป็นจำนวนคี่ระหว่าง ตรงกันข้ามการเข้าสู่ระบบไม่ได้รับอนุญาตให้เปลี่ยนหลังจากที่แม้จำนวนเลขศูนย์


ฉันใช้สิ่งนี้โดยแต่ละอาร์เรย์หาศูนย์แรก -1ผมตัดศูนย์ออกและคูณองค์ประกอบทั้งหมดหลังจากที่มันโดย สำหรับผลลัพธ์สุดท้ายหมายความว่าองค์ประกอบทั้งหมดจะต้องมีเครื่องหมายเดียวกัน แน่นอนว่ามีปัญหาเล็กน้อยของการ-3เสมอภาค+1และ2ไม่ได้รับอนุญาตโดยทั่วไป ฉันแก้ไขสิ่งนี้ด้วยการใช้การรวมกลุ่มของผลลัพธ์ด้วย[1 -3]และตรวจสอบว่านี่เป็นขนาด 2 หรือไม่ ทำซ้ำ[-1 3]และตรวจสอบว่า (หรือทั้งสองอย่างในกรณีของอินพุต 1 ความยาว) เป็นจริงหรือไม่

d                                % Difference of input
 t~a                             % Check if any element equals 0
    X`                     t~a]  % Start while loop, ending in the same check
       t~                           % Get a new vector, logical negated to find zeroes.
          f1)                       % Find the position of the first zero. 
      t         q:)                 % Decrement by 1, to index all elements before that zero.
                   w3MQJh)          % Push the result of 'find', but increment to get all elements after.
                         _h         % Multiply the second half by -1, and concatenate horizontally.

  T-3hX|n2=                      % Check if set union with [1 -3] is size 2
 t        wT_3hX|n2=             % Check if set union with [-1 3] is size 2
                    +            % Logical OR. 

@LuisMendo ขอบคุณ ฉันจำเป็นต้องอ่านข้อมูลจริง ๆMครั้งล่าสุดที่ฉันลองใช้งานมันทำงานต่างไปจากที่คาดไว้ดังนั้นฉันจึงไม่สนใจมันในตอนนี้ มันเป็นสิ่งที่ถูกต้องที่จะบอกว่าจะต้อง3Mแล้วเพราะฉันได้รับการป้อนข้อมูลของไม่ได้)ไม่ได้:แต่ของq(ข้ามwในขณะที่มันไม่ได้เป็นปกติฟังก์ชั่น)?
Sanchises

ใช่แล้ว wถูกข้ามเนื่องจากไม่ใช่ฟังก์ชั่นปกติ ฟังก์ชั่นปกติที่ไม่มีอินพุตจะถูกข้ามเช่นกัน
Luis Mendo

2

Python (3.5) 160 151 150 ไบต์

โซลูชันแบบเรียกซ้ำ

def f(s):g=lambda s,c:s==''or g(s[1:],(c[:4]*2)[(s[0]==c[0])*2+1:])if s==''or s[0]in c[:2]else 0;return any([g(s,"1234123"[i:])for i in range(4)])

Ungolfed โดยไม่ต้องแลมบ์ดา

def f(s):
    def g(s,c):
        if s=='' or s[0] in c[:2] :
            return s=='' or g(s[1:],(c[:4]*2)[(s[0]==c[0])*2+1:])
        else:
            return False
    return any([g(s,"1234123"[i:]) for i in range(4)])

ฉันหมุนกล่องทั้งหมดแทนที่จะหมุน ตำแหน่งข้อเหวี่ยงอยู่ระหว่างอักขระตัวแรกและตัวที่สองของสตริง c ฉันต้องทดสอบตำแหน่งเริ่มต้นทั้งหมดของข้อเหวี่ยง

เคล็ดลับที่ใช้ในการหมุนสตริง

วิธีปกติในการหมุนสตริงในไพ ธ อน ( s[i:]+s[:i]) จำเป็นต้องทำซ้ำทั้งดัชนีและสตริง ในกรณีนี้ฉันทำซ้ำสตริงและครอบตัดอักขระแรก

(c*2)                        # duplicate the string
     [(s[0]==c[0])*2+1       # test that return 1 if firsts characters match 3 instead 
                      :]     
                        [:4] # crop again to have a 4 characters string

กรณีทดสอบ

[f(i) for i in ["1", "1234", "1221", "3333", "143332", "22234", "2234", "22214", "1221441", "41233", "13", "1224", "121", "12221", "43221"]]
[True, True, True, True, True, True, True, True, True, True, False, False, False, False, False]

1
3"[i:]) forคุณสามารถลบพื้นที่ที่
Erik the Outgolfer

@EriktheOutgolfer ขอบคุณฉันลบมัน
Erwan


1

JavaScript (ES2015) 110 95

p=(s,d)=>(h=s[0],t=s.slice(1),g=t[0],!g||(d?g==h?p(t,-d):g%4==(h-d)%4&&p(t,d):p(s,1)||p(s,-1)))

บันทึก 15 ไบต์โดย Neil! เวอร์ชันเดิมไม่ได้รับการดัดแปลง:

p = (s, d) => {
  h = s[0]
  t = s.substr(1)

  if (!t[0]) return true
  if (!d) return p(s, 1) || p(s, -1)
  if (t[0] == h) return p(t, d*-1)
  if (t[0] == (h-d > 4 ? 1 : h-d || 4)) return p(t, d)

  return false
}

การทดสอบ: https://jsbin.com/cuqicajuko/1/edit?js,console


1
บันทึกคุณ 17 ไบต์:(s,d)=>(h=s[0],t=s.slice(1),g=t[0],!g||(d?g==h?p(t,-d):g%4==(h-d)%4&&p(t,d):p(s,1)||p(s,-1)))
Neil

ยังไม่สั้นเท่ากับคำตอบของ @ user81655
Neil

1

ทัวริงรหัสเครื่อง 395 ไบต์

0 1 _ r a
0 2 _ r b
0 3 _ r c
0 4 _ r d
a 1 _ r a
a 2 _ r E
a 3 _ r h
a 4 _ r S
b 1 _ r W
b 2 _ r b
b 3 _ r S
b 4 _ r h
c 1 _ r h
c 2 _ r N
c 3 _ r c
c 4 _ r W
d 1 _ r N
d 2 _ r h
d 3 _ r E
d 4 _ r d
N 1 _ r W
N 2 _ r E
N _ _ r r
N * _ r h
E 2 _ r N
E 3 _ r S
E _ _ r r
E * _ r h
S 3 _ r E
S 4 _ r W
S _ _ r r
S * _ r h
W 4 _ r S
W 1 _ r N
W _ _ r r
W * _ r h
h _ 0 r halt
h * _ r h
r _ 1 r halt

ลองออนไลน์!

นี่เป็นวิธีการพื้นฐานของรัฐ:

  • สถานะเริ่มต้นคือ 0
  • a, b, cและdเป็น "ลังเลฯ" ที่จะเกิดขึ้นที่จุดเริ่มต้น
  • N, E, SและWเป็น "รัฐตัดสินใจ" เห็นได้ชัดว่ายืนNorth, EAST, South และWEST

1

ถึง 203 ไบต์

ฉันคิดไม่ออกว่าจะตีกอล์ฟไกลกว่านี้อย่างไร

0::=:::
>11::=>1
>22::=>2
>33::=>3
>44::=>4
>12::=b
>21::=d
>14::=c
>41::=a
>23::=c
>32::=a
>34::=d
>43::=b
a1::=d
a2::=b
b2::=a
b3::=c
c3::=b
c4::=d
d4::=c
d1::=a
a<::=~n
b<::=~e
c<::=~s
d<::=~w
::=
>0<

หากลำดับของบันทึกย่อเป็นไปได้จะเป็นทิศทางสิ้นสุดของเอาต์พุตมิฉะนั้นเอาต์พุตจะว่างเปล่า


1

Prolog (SWI) , 117 ไบต์

a(N,P):-P=N;N=1,P=4,!;P is N-1.
m([A,B|C],[X,Y|Z]):-a(A,X),a(B,X),a(B,Y),X\=Y,m([B|C],[Y|Z]).
m([_],_).
p(N):-m(N,_).

กำหนดเพรดิเคตpที่ประสบความสำเร็จกับอินพุตที่สามารถเล่นได้ (กำหนดเป็นรายการของจำนวนเต็ม) และล้มเหลวกับอินพุตที่ไม่สามารถเล่นได้ ลองออนไลน์!

คำอธิบาย

aกำหนดความสัมพันธ์ระหว่างถ้อยคำทราบและตำแหน่งข้อเหวี่ยงN Pเรากำหนดตำแหน่งหน้าจะอยู่ระหว่างบันทึกPและP + 1 ดังนั้นตำแหน่งที่อยู่ติดกันเพื่อทราบNiff

  • มันเท่ากับN( P=N); หรือ
  • หมายเหตุคือ 1 และตำแหน่งคือ 4 ( N=1,P=4); หรือ
  • กรณีข้างต้นไม่เป็นจริง ( !) และตำแหน่งเท่ากับN-1( P is N-1)

mใช้รายการบันทึกย่อและพยายามสร้างรายการตำแหน่งที่จะเล่นโน้ตเหล่านั้น Aเป็นโน้ตที่เพิ่งเล่นหรือBคือโน้ตที่กำลังจะเล่น Xคือตำแหน่งข้อเหวี่ยงปัจจุบันYเป็นตำแหน่งข้อเหวี่ยงถัดไป การย้ายที่ถูกต้อง iff

  • โน้ตที่เพิ่งเล่นนั้นอยู่ติดกับตำแหน่งข้อเหวี่ยงปัจจุบัน ( a(A,X));
  • หมายเหตุเกี่ยวกับการเล่นยังอยู่ติดกับตำแหน่งข้อเหวี่ยงปัจจุบัน ( a(B,X));
  • หมายเหตุเกี่ยวกับการเล่นอยู่ติดกับตำแหน่งข้อเหวี่ยงถัดไป ( a(B,Y)); และ
  • ตำแหน่งข้อเหวี่ยงสองตำแหน่งไม่เท่ากัน ( X\=Y)

หากสิ่งเหล่านี้ถือเป็นเงินชดเชย หากเราประสบความสำเร็จในการจดบันทึกใด ๆ หนึ่ง ( m([_],_)) ลำดับของโน้ตนั้นสามารถเล่นได้

สำหรับคำถามนี้เราเพียงแคร์ว่ามีลำดับของการเคลื่อนไหวอยู่หรือไม่ดังนั้นเราจึงกำหนดpให้การโทรmและทิ้งรายการตำแหน่งของข้อเหวี่ยงที่สร้างขึ้น

ดูรุ่น ungolfed และตรวจสอบกรณีทดสอบทั้งหมดที่นี่

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