คณิตศาสตร์คือข้อเท็จจริง การเขียนโปรแกรมไม่ได้


175

ในคณิตศาสตร์เครื่องหมายอัศเจรีย์!มักหมายถึงแฟกทอเรียลและเกิดขึ้นหลังจากการโต้แย้ง

ในการเขียนโปรแกรมเครื่องหมายอัศเจรีย์!มักหมายถึงการปฏิเสธและเกิดขึ้นก่อนการโต้แย้ง

สำหรับความท้าทายนี้เราจะใช้การดำเนินการเหล่านี้กับศูนย์หนึ่งเท่านั้น

Factorial
0! = 1
1! = 1

Negation
!0 = 1
!1 = 0

ใช้สตริงของศูนย์หรือมากกว่า!ตามด้วย0หรือ1ตามด้วยศูนย์หรือมากกว่า!( /!*[01]!*/)
ยกตัวอย่างเช่นการป้อนข้อมูลที่อาจจะ!!!0!!!!หรือ!!!1หรือ!0!!หรือหรือ0!1

สิ่งที่!อยู่ก่อนหน้า0หรือ1ถูกปฏิเสธและสิ่ง!ที่ตามมาคือแฟคทอเรียล

แฟคทอเรียลมีความสำคัญสูงกว่าการปฏิเสธดังนั้นแฟคทอเรียลจะถูกใช้ก่อนเสมอ
ยกตัวอย่างเช่น!!!0!!!!อย่างแท้จริงหมายถึงหรือยังดีกว่า!!!(0!!!!)!(!(!((((0!)!)!)!)))

เอาต์พุตแอพพลิเคชั่นผลลัพธ์ของแฟคทอเรียลและการปฏิเสธทั้งหมด การส่งออกจะเป็นหรือ01

กรณีทดสอบ

0 -> 0
1 -> 1
0! -> 1
1! -> 1
!0 -> 1
!1 -> 0
!0! -> 0
!1! -> 0
0!! -> 1
1!! -> 1
!!0 -> 0
!!1 -> 1
!0!! -> 0
!!!1 -> 0
!!!0!!!! -> 0
!!!1!!!! -> 0

รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ


18
แต่ 0! = 1! ดังนั้นประเด็นของการจัดการปัจจัยหลายอย่างคืออะไร
boboquack

30
@boboquack เพราะนั่นเป็นความท้าทาย
งานอดิเรกของ Calvin

11
<= '1'; ... แก้ไข 75% ของเวลาเป็น php
aslum

10
ฉันอาจจะผิดที่นี่ แต่ตัวเลขไม่สามารถใด ๆ กับ factorials ใด ๆ หลังจากที่มันถูกลบและแทนที่ด้วย 1? ชอบ 0 !!!! = 1 !! = 0 !!!!!!!! = 1 !!! = 1! = 0! = 1 ฯลฯ
Albert Renshaw

2
@AlbertRenshaw นั่นถูกต้อง
งานอดิเรกของ Calvin

คำตอบ:


43

Mathematica, 25 17 ไบต์

Input[]/.!x_:>1-x

รับอินพุตจากพรอมต์ของผู้ใช้ ถือว่าสภาพแวดล้อมโน้ตบุ๊คของ Mathematica สำหรับการพิมพ์โดยนัย จะทำให้มันเป็นสคริปต์บรรทัดคำสั่งห่อไว้ในPrint[...]หรือเพื่อทำให้มันเป็นฟังก์ชั่น argumentless (ซึ่งแล้วจะใช้เวลาการป้อนข้อมูลจากพรอมต์) &ผนวก

Mathematica มีทั้งโอเปอเรเตอร์ที่จำเป็น (ด้วยความสำคัญที่ต้องการ) ดังนั้นเราสามารถ "eval" อินพุต (ซึ่งทำโดยอัตโนมัติInput[]) แต่โอเปอเรเตอร์การปฏิเสธแบบตรรกะไม่ทำงานบนจำนวนเต็ม (ดังนั้นมันจะยังคงประเมิน) หากมีเหลืออยู่ในผลที่เราแทนที่ด้วย!x1-x

ข้อเท็จจริงสนุก ๆ เกี่ยวกับการประเมิน:

  1. Mathematica ยังมีตัวดำเนินการแบบสองหน่วย!!ซึ่งคำนวณn*(n-2)*(n-4)*...แต่นำไปใช้กับ0หรือ1ยังคงให้1ดังนั้นจึงไม่สำคัญว่า0!!!!!จะแยกวิเคราะห์เป็น((0!!)!!)!จริง
  2. แม้ว่า Mathematica ใบ!0และ!1unevaluated ก็ไม่ทราบว่าเป็นตัวผกผันจึงจะยกเลิกทุกคู่นำโดยอัตโนมัติ! !หลังจากที่ToExpressionเรามักจะทิ้งให้อยู่กับหนึ่ง0, 1, ,!0!1

3
ตั้งแต่เมื่อไรที่ข้อมูลโค้ด REPL อนุญาตโดยค่าเริ่มต้น
LegionMammal978

2
@ LegionMammal978 เห็นได้ชัดตั้งแต่ธันวาคม 2558 แต่ฉันลืมมันไปเรื่อย ๆ เพื่อความเป็นธรรมมันไม่ใช่ "ตัวอย่าง" ในการที่มันไม่ได้คิดว่าการป้อนข้อมูลจะถูกเก็บไว้ที่ไหนสักแห่งในหน่วยความจำ และสมมติว่าสภาพแวดล้อมของโน้ตบุ๊กนั้นไม่แตกต่างจากภาษาที่มีเอาต์พุตโดยปริยาย
Martin Ender

แค่สงสัยเมตาลิงค์สามารถให้ได้หรือไม่ (พยายามค้นหาข้อมูลที่มีความเครียด แต่เป็นอีกปัญหาหนึ่งของรูปแบบคำถาม & คำตอบ
SEA

@ LegionMammal978 มันมีอยู่แล้วในคำตอบ
Martin Ender

วิธีแก้ปัญหา ksh บริสุทธิ์x=${x/[01]!*/1};echo $(($x))- ไม่อนุญาตให้โพสต์คำตอบที่ถูกต้อง :(
DarkHeart

28

[Bash] + ยูทิลิตี้ Unix, 21 17 ไบต์

sed s/.!!*$/1/|bc

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

กรณีทดสอบรัน:

for x in 0 1 '0!' '1!' '!0' '!1' '!0!' '!1!' '0!!' '1!!' '!!0' '!!1' '!0!!' '!!!1' '!!!0!!!!' '!!!1!!!!'; do ./excl <<<"$x"; done

0
1
1
1
1
0
0
0
1
1
0
1
0
0
0
0

เวอร์ชั่นเก่าใช้งานได้ แต่อันนี้ไม่ได้
วัวต้มตุ๋น

ฉันใช้ลิงก์ TIO
วัวต้มตุ๋น

@KritixiLithos มันใช้ได้ดีเมื่อฉันลองมันในกล่อง Linux ของฉัน เห็นได้ชัดว่ามีปัญหาว่า TIO ต้องขึ้นบรรทัดใหม่ที่ท้ายบรรทัดอินพุตที่จำลองขึ้นมา มันเป็นสถานการณ์ที่สับสนดังนั้นฉันจึงถอดลิงค์ TIO ออก หากคุณต้องการลองที่นี่นี่ลิงค์อีกครั้ง (แต่ให้แน่ใจว่าได้รวมบรรทัดใหม่ในตอนท้ายของอินพุตถ้าคุณเปลี่ยนอินพุตเพื่อทดสอบออก): tio.run/nexus/bash#@1@cmqJQrK @ nqKilom @ oX5OU / P @ / …
Mitchell Spector

2
แต่ถ้ามีใครวิ่งmkdir -p 's/.!!'{bunch,of,different,directories}\$/1บ้าง จากนั้นคุณจะได้รับPathname Expansionและ Sed จะพยายามอ่านไดเรกทอรีราวกับว่าเป็นไฟล์แทนที่จะอ่านอินพุตมาตรฐานและมันจะไม่เอาท์พุทอะไรเลย! :)
ไวด์การ์ด

1
@ Wildcard ฉันเห็นด้วยอย่างสมบูรณ์ ในสคริปต์การผลิตฉันมักจะใช้เครื่องหมายคำพูดในสถานการณ์เช่นนี้ (ในกรณีนี้ฉันจะใส่เครื่องหมายอัญประกาศล้อมรอบอาร์กิวเมนต์มากกว่าที่จะหลบหนี * มันง่ายต่อการอ่านมากกว่าการใช้แบ็กสแลชและหลีกเลี่ยงความเป็นไปได้ที่จะขาดอักขระพิเศษบางตัว)
Mitchell Spector

22

Retina , 20 15 14 ไบต์

ขอบคุณ Leo ที่ช่วยประหยัด 1 ไบต์

0!
1
!!

^1|!0

ลองออนไลน์!

คำอธิบาย

0!
1

เลี้ยวเข้าไป0! 1เราไม่สนใจเกี่ยวกับส่วนท้ายอื่น ๆ!จำนวนผลลัพธ์ที่ได้จะเหมือนกับว่าเราใช้แฟคทอเรียลทั้งหมด

!!

ยกเลิกคู่การปฏิเสธ สิ่งนี้อาจยกเลิกแฟกทอเรียลบางอย่าง แต่ไม่เกี่ยวข้อง

^1|!0

นับจำนวนการแข่งขันของ regex นี้ซึ่งเป็นอย่างใดอย่างหนึ่ง1หรือ0และให้ผลลัพธ์ที่ต้องการ


โซลูชันอื่นสำหรับจำนวนเดียวกัน: \d.+...
วัวต้มตุ๋น

@KritixiLithos ค้นพบวิธีการหลีกเลี่ยงสิ่งนั้นโดยสิ้นเชิง
Martin Ender

คุณสามารถลบรายการ^ก่อนหน้า!0
Leo

17

Grime , 14 12 9 ไบต์

e`\0!~\!_

ลองออนไลน์!

คำอธิบาย

นี่ตรงกับอินพุตกับรูปแบบการพิมพ์1สำหรับการจับคู่และ0ไม่ตรงกัน

e`\0!~\!_
e`         Match entire input against this pattern:
    !      not
  \0       a sole 0
     ~     xor
      \!   exclamation mark
        _  followed by this pattern matched recursively.

ความคิดคือสิ่งนี้ ถ้าใส่เริ่มต้นด้วยหลักแล้วส่วน recursive \!_เสมอล้มเหลวและประสบความสำเร็จถ้าเรามีเพียงหนึ่งเดียว\0! 0xor 0ของพวกเขาประสบความสำเร็จเว้นแต่เข้าเป็นหนึ่งเดียว หากอินพุตเริ่มต้นด้วย a !ดังนั้น\0!จะสำเร็จเสมอและ\!_ประสบความสำเร็จหากการจับคู่แบบซ้ำสำเร็จ xor ของพวกเขาประสบความสำเร็จอย่างแน่นอนเมื่อการแข่งขันแบบเรียกซ้ำล้มเหลว


16

Brainfuck, 85 72 (84) ไบต์

,[>-[-----<->]<++[>++++[-<++++>]+<[[+],[[-]>-<]]]>[<<+[-->]>[<],>-]<]<+.

เพื่อส่งคืนตัวเลขหรือ

,[>-[-----<->]<++[>++++[-<++++>]+<[[+],[[-]>-<]]]>[<<+[-->]>[<],>-]<]-[-----<+>]<--.

สำหรับข้อความ ASCII > อาจถูกนำหน้าเพื่อป้องกันการตัดหน่วยความจำ

ลองออนไลน์!


Loops over the input.
On 1, ends.
On "!", toggles bool a stored as 0 or 255.
On "0", toggles if there is no trailing bit, then ends.

Memory labels  | BOOL | INPUT | FLAG |

,                   first input 
[                     # loop on INPUT
  >-[-----<->]<++     subtract 49 == "1"

  [                     # case not "1"
    >++++[-<++++>]      add 16 since 49 take 16 == "!"

    +                   set FLAG
    <                   move to INPUT
    [                     # case "0"
      [+],                clear and new INPUT
      [                     # case "0!"
        [-]>-<              clear INPUT and FLAG
      ]
    ]
  ]

  >                   move to FLAG
  [                     # case "!" or "0" without tail
    <<+[-->]>[<]        not the BOOL
    ,                   take new input
    >-                  clear FLAG
  ]
  <                   move to INPUT
]

+.                    return 0 or 1

หรือสำหรับการตอบกลับข้อความให้แทนที่บรรทัดสุดท้ายด้วย

-[-----<+>]<--.       add 49 for "0" or "1" conversion and return

14

Brainfuck - หลายไบต์ (232 ไบต์)

เห็นได้ชัดว่าภาษาผิดสำหรับการชนะในการแข่งขันกอล์ฟ ส่วนใหญ่ฉันสังเกตเห็นว่าไม่มีใครใช้ esolang นี้ มีล่ามออนไลน์bf interpeter ที่ดีหรือคุณสามารถดูว่าโปรแกรมใช้bf visualizerนี้หรือไม่

>>>>>,[>+++[<---------------->-]<<<<<<[-]+>[-]>>>>[-[<<[>+<<<<->>>[<<+>>-] ]<<[>>+<<-]<[>>+<<[-]]>>>>>[-]]<<<<<[>>>++<<<-]>+>>>>[-]]<<<<-[>>+<<[-]]>>>>,]<<->[<[-]+>[-]]<<[<[-]>>[<<+>>[-]]+<<[->>-<<]>-]>>[-]+++[<++++++++++++++++>-]<.

3
คุณเป็นคนบ้า !!
Almo

รักเลยคุณสามารถทำสิ่งนั้นได้ใน malbolge หรือไม่? XD
Stefan Nolde

ข้อมูล: มีวิธีแก้ปัญหาที่สั้นกว่ามากเกินไปด้านล่าง
user202729

14

Python, -44- 42 ไบต์

บันทึก 2 ไบต์ด้วย Zgarb!

lambda x:(x[-1]=='0')^len(x.rstrip('!'))%2

เป็นขั้นเป็นตอน:

  1. x[-1]!='0'
    หากxลงท้ายด้วย1หรือ!xไม่ได้ลงท้ายด้วย0ส่วนแฟคทอเรียลจะต้องมีค่า1เป็นอย่างอื่น0
  2. ^len(x.rstrip('!'))%2
    ใช้ประโยชน์จากคุณสมบัติของ xor ในฐานะ "ไม่เป็นเงื่อนไข" เงื่อนไขในกรณีนี้คือถ้าความยาวของ!s เริ่มต้นเป็นคี่ อย่างไรก็ตาม.rstripอย่าลบหมายเลขออกจากสตริงดังนั้นความยาวที่คำนวณได้จะถูกชดเชยด้วย 1 ดังนั้นเงื่อนไขจึงกลับด้าน
  3. ออฟเซ็ตทีละ 1 ในขั้นตอนที่ 2 ได้รับการแก้ไขโดยการเปลี่ยน!=เป็น==ในขั้นตอนที่ 1 Zgarb แนะนำให้ใช้ตัวดำเนินการเปรียบเทียบความแตกต่าง

ลองออนไลน์!


ล้มเหลวในอินพุตของ!!0; 1มันกำลังจะกลับมา
หมึกมูลค่า

@ValueInk ควรทำงานตอนนี้
busukxuan

1
lambda x:(x[-1]=='0')^len(x.rstrip('!'))%2หลีกเลี่ยงการผกผันพิเศษ
Zgarb

15
มีการข้ามกัน 44 ยังคงเป็นปกติ 44
Rɪᴋᴇʀ

3
ฉันคิดว่าเขาระบุว่ามีการขีดฆ่า 44 ตัวอักษรที่ใช้ไม่ได้มองข้าม ... :) ส่วนกากบาททับซ้อนกับส่วนแนวนอนของ 4s
JeffC

13

JavaScript (ES6), 43 41 29 ไบต์

s=>+eval(s.replace(/.!+$/,1))

วิธีการที่ไม่ใช่ regex ( 41 31 ไบต์)

ด้านล่างเป็นวิธีการเริ่มต้นของฉัน มันเป็นเรื่องเล็กน้อยที่น่าสนใจ แต่อย่างมีนัยสำคัญอีกต่อไป ยังคงอีกนานแม้หลังจากการเพิ่มประสิทธิภาพอย่างมีนัยสำคัญโดยนีล (10 ไบต์บันทึกไว้)

f=([c,...s])=>1/c?c|s>'':1-f(s)

กรณีทดสอบ


ฉันเท่านั้นที่สามารถบันทึก 10 ไบต์จากวิธีที่ไม่ใช่ regex f=([c,...s])=>1/c?c|s>'':1-f(s)ของคุณเพื่อให้มันยังคงยาวเกินไป:
Neil

@ Neil เนื่องจากมันดีกว่าความพยายามครั้งแรกของฉันอยู่แล้วฉันจึงมีเสรีภาพที่จะรวมข้อเสนอแนะของคุณ
Arnauld

ฮ่าฉันมีความคิดเดียวกัน แต่คุณเล่นกอล์ฟได้ดีกว่า :)
Devsman

11

เยลลี่ 5 ไบต์

VeMḂ$

ลองออนไลน์!

ฟังก์ชัน Monadic ต้องการสตริง อินพุตที่มีการนำหน้า!ทำให้ a 1ถูกพิมพ์ไปที่ STDOUT ตลอดเส้นทางดังนั้นลิงค์ TIO ที่ฉันให้คือชุดทดสอบที่พิมพ์คู่อินพุต - เอาต์พุตที่อยู่ใต้บรรทัดแรกของเอาต์พุต

อย่างไร?

VeMḂ$ - Monadic link: string
V     - eval the string
          - the implicit input of 0 causes !...! to evaluate to 1 (which gets printed),
          - the result is the evaluation of the rest: "0"=0; "0!"=1; "1"=1; "1!"=1; ...
 e    - exists in?
    $ - last two links as a monad:
  M   -     Maximal indexes - the "0" and "1" characters are greater than "!",
                            - so this results in a list of one item [i] where
                            - i is the 1-based index of the 0 or 1 character.
   Ḃ  -     %2 (vectorises) - [i%2], so a 0 if we need to logically negate and a 1 if not
                            - hence we check equality with e rather than inequality.

10

05AB1E , 9 ไบต์

รหัส:

.V¹'!ÜgG_

ใช้การเข้ารหัสCP-1252 ลองออนไลน์! หรือตรวจสอบกรณีทดสอบทั้งหมด!

คำอธิบาย:

.V         # Evaluate the input as 05AB1E code. This computes the factorial part.
   '!Ü     # Remove trailing exclamation marks..
  ¹        # ..from the first input
      g    # Get the length of the resulting string
       G   # Do the following length - 1 times:
        _  #   Negate the number

10

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

วิธีการที่ค่อนข้างแปลก แต่มันสั้นและใช้งานได้

0$
!1
!!

^\d

ด้วยสองบรรทัดแรกเราแทนที่ลงท้าย0ด้วย!1: ด้วยการแทนที่นี้ตอนนี้เรารู้ว่าส่วนของสตริงของเราจากตัวเลขเป็นต้นไปเท่ากับ 1

อีกสองบรรทัดถัดไปลบคู่ของ!: การปฏิเสธคู่ลบตัวเองและเราคำนึงถึงแฟกทอเรียลกับขั้นตอนก่อนหน้านี้แล้ว

บรรทัดสุดท้ายจับคู่ตัวเลขที่จุดเริ่มต้นของสตริงและคืนจำนวนการจับคู่: หากการคัดค้านถูกตัดออกทั้งหมดเราจะพบการแข่งขัน (และอย่างที่เราพูดก่อนที่เราจะรู้ว่านี่เท่ากับ 1) หากยังมี การปฏิเสธนี้จะไม่ตรงกัน

ลองออนไลน์!


1
ตัวเลขสุดท้ายไม่จำเป็นต้องเป็น 1 เสมอหรือไม่ ในกรณีที่คุณสามารถใช้มากกว่า1 \d

1
@ ais523 ไม่เพราะส่วนแรกจะแทนที่ 0 สิ้นสุดเท่านั้นดังนั้นตัวอย่างเช่นอินพุต0!จะไม่เปลี่ยนแปลงจนกว่าบรรทัดสุดท้าย
Leo

1
ทางออกที่น่ารักจริง ๆ การทำงานที่ดี! :)
Martin Ender

10

Ruby, 12 + 1 = 39 24 15 13 ไบต์

ใช้-nธง ขอบคุณ@GBสำหรับ -9 ไบต์!

p~/!*$|0$/%2

เนื่องจากคุณตรวจสอบความยาวเพียงอย่างเดียวคุณสามารถลบศูนย์ต่อท้ายแทนที่จะตรวจสอบ "! 0" ก่อนและศูนย์เดียวหลังจากนั้น
GB

@GB นั่นเป็นความคิดที่ยอดเยี่ยม! อย่างไรก็ตามฉันพบวิธีแก้ไขปัญหาที่สั้นลงโดยการแก้ไข regex ของฉันเพื่อค้นหาตำแหน่ง0 หรือจุดสิ้นสุดของบรรทัด
Value Ink

จากนั้นคุณสามารถตรวจสอบการลาก '!' หรือศูนย์หรือจุดสิ้นสุดของบรรทัด: p ~ /! + $ | 0 $ | $ /% 2 เป็นเพียง 14 ไบต์
GB

จากนั้น "0 $ | $" อาจกลายเป็น "0? $" เพื่อบันทึกไบต์อื่น
GB

1
ดีกว่า แต่!*$สั้นกว่าสองเท่า!
หมึกมูลค่า

9

Perl , 20 ไบต์

19 ไบต์ของรหัสเมือง + -pธง

s/\d!+/1/;$_=0+eval

ลองออนไลน์!

Perl ของผลตอบแทนการปฏิเสธundefหรือ1ดังนั้นฉันจะใช้0+เพื่อ numerify ผลตอบแทนที่0+undef 0นอกจากนั้นไม่มากที่จะพูดเกี่ยวกับรหัส


2
แค่เขียนตรงนี้ มี +1
โม่

@primo ดีใจที่ได้เห็นครั้งหนึ่งผมไม่ได้อยู่ข้างหลังคุณ 20 ไบต์! ขอบคุณ :)
Dada

9

C, 68 62 61 53 ไบต์

c;e(char*a){for(c=1;*a<34;a++)c^=1;c=a[1]?c:*a&1^!c;}

บีบออกอีกไม่กี่ไบต์ด้วยการใช้งานในทางที่ผิด

ลองออนไลน์!


1
ฉันคิดว่าคุณสามารถลบintจากฟังก์ชั่นและคุณสามารถเปลี่ยนไป*a==33 *a<34
วัวนักต้มตุ๋น

อนิจจา*a%2สั้นกว่า*a-48
วัวต้มตุ๋น

ขอบคุณสำหรับทิป. ฉันยังสามารถกำจัดตัวละครอื่นโดยการลบวงเล็บไปรอบ ๆ ผลตอบแทนและกำหนดมัน
Ahemone

ฉันค่อนข้างมั่นใจว่าfor(;*a<34;a++)สามารถลดขนาดให้เหลือเพียงfor(;*a++<34;)1 ไบต์
Albert Renshaw

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

6

Perl 6 , 32 28 23 ไบต์

{m/(\!)*(1|0.)*/.sum%2}

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

{                     }  # A lambda.
{m/            /      }  # Match the lambda argument against the regex:
   (\!)*                 #   Zero or more `!`.
                         #     (First capture will be an array with one element per negation).
        (1|0.)*          #   A `1`, or a `0` and another character, zero or more times.
                         #     (Second capture will be a one-element array if the factorial
                         #     part evaluates to 1, and an empty array otherwise.)
                .sum     # Add the lengths of the two captures,
                    %2   # and return that sum modulo 2.

6

Haskell , 39 ไบต์

f('!':b)="10"!!read[f b]
f[a]=a
f _='1'

กำหนดฟังก์ชั่นfซึ่งใช้สตริงและส่งกลับตัวละคร ลองออนไลน์!

คำอธิบาย

มีสามกรณี: อินพุตเริ่มต้นด้วย!อินพุตมีความยาว 1 และทุกอย่างอื่น

f('!':b)=    -- If input has head '!' and tail b,
 "10"!!      -- we index into the string "10"
  read[f b]  -- using f b converted to int. This essentially inverts f b.
f[a]=        -- If input has only one character, we know it's a digit,
 a           -- so we can just return it.
f _=         -- In all other cases, we know the input is a digit followed by !s,
 '1'         -- so we can return '1'.

เปลี่ยนจาก String f('!':b)=[1,0]!!f b;f"0"=0;f _=1จะเป็นชนิดจำนวนเต็มสิ่งตอบแทน:
nimi

6

Befunge ขนาด 24 ไบต์

~"!"-:#v_$1+
*+2%!.@>0~`

ลองออนไลน์!

สิ่งนี้เริ่มต้นด้วยการนับจำนวน!ตัวอักษรที่อ่านจาก stdin ตัวละครตัวแรกที่ไม่ใช่!พินัยกรรมจะเป็น0หรือ1แต่ในกระบวนการทดสอบ!เราจะได้ลบ 33 ทำให้เป็น 15 หรือ 16 จากนั้นเราอ่านอักขระอีกหนึ่งตัวซึ่งจะเป็น!EOF และ เปรียบเทียบว่ามันน้อยกว่า 0 (เช่น EOF)

การรับจุดข้อมูลทั้งสาม - การนับอัศเจรีย์ ( c ), ค่าตัวเลข, ( d ), และเงื่อนไขสิ้นสุดไฟล์ ( e ) - เราสามารถคำนวณผลลัพธ์ดังนี้:

!((c + d*e) % 2)

การคูณค่าตัวเลขด้วยเงื่อนไขสิ้นสุดไฟล์หมายความว่ามันจะถูกแปลงเป็นศูนย์หากตัวเลขตามด้วย a !ดังนั้นจึงให้ค่า modulo 2 เช่นเดียวกับ a 1(ซึ่งจำได้ถูกแปลงเป็น 16) แต่ก่อนที่จะใช้โมดูโล 2 เราจะเพิ่มการนับจำนวนเริ่มต้นด้วยเครื่องหมายอัศเจรีย์ซึ่งจะสลับการโมดูโล 2 ได้อย่างมีประสิทธิภาพหลาย ๆ ครั้งเช่นเดียวกับ!คำนำหน้า และในที่สุดเราก็ไม่ได้ผลลัพธ์เนื่องจากค่าพื้นฐานของเราสำหรับ0และ1ตรงข้ามกับสิ่งที่เราต้องการ

ดูรหัสในรายละเอียดเพิ่มเติม:

~                Read a character from stdin.
 "!"-            Subtract 33 (ASCII for '!').
     :  _        Make a duplicate and check if zero (i.e. is it a '!').
         $1+     If so, drop the duplicate, increment a counter, and repeat.
       v         Otherwise move to the second line, leaving the digit value on the stack.
       >0~`      Read one more character and check if less than 0 (i.e. EOF).
*                Multiple by the digit value, making it zero if not followed by EOF.
 +               Add to the exclamation count.
  2%             Modulo 2 the result.
    !            Then not that value.
     .@          And finally write to stdout and exit.

6

Haskell , 27 ไบต์

f('!':b)=1-f b
f"0"=0
f _=1

ลองออนไลน์!

แต่ละชั้นนำในการเติมเต็มการส่งออกสำหรับส่วนที่เหลือของการแสดงออกที่ทำได้เช่น! 1-เราพลิกต่อไปจนกว่าเราจะตีตัวเลข หากส่วนที่เหลือเป็นเพียง"0"ผลลัพธ์จะเป็น 0 มิฉะนั้นจะเป็น a 1หรือตามด้วยอย่างน้อยหนึ่ง!ผลลัพธ์จึงเป็น 1


5

Ruby, 22 21 20 ไบต์

->s{(s=~/!*$|0$/)%2}

คำอธิบาย:

  • กรณีแรกฉันได้รับ '!' ในตอนท้ายลบออกรับความยาวแบบโมดูโล 2
  • ตัวพิมพ์ที่สองไม่ใช่ '!' ถ้าตัวอักษรตัวสุดท้ายเป็นศูนย์ให้ลบออกให้ได้ความยาวแบบโมดูโล 2
  • หากอักขระตัวสุดท้ายคือ 1 ให้กลับไปที่ตัวพิมพ์แรก

(-1 ไบต์ขโมยแนวคิดของ @Value Ink)


ยอดเยี่ยมฉันดูปริศนานี้เป็นเวลา 10 นาที แต่มีเวลาไม่มากแล้วลืมมันไป ตอนนี้พบอีกครั้งในคำถามที่ใช้งานและมีความยินดีที่จะเห็นวิธีการที่ดี
akostadinov

4

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

œr”!LḂ=V

ลองออนไลน์!

นี่คือฟังก์ชั่น (ลิงค์ monadic) ที่รับอาร์กิวเมนต์หนึ่งตัวและส่งคืนผ่านค่าส่งคืน (มันมักจะเขียนขยะไปยังเอาต์พุตมาตรฐานเป็นผลข้างเคียง แต่เราไม่สนใจสิ่งนั้น)

คำอธิบาย

œr”!LḂ=V
œr”!      Take {the input}, with all trailing ! deleted
    L     Take the length of this
     Ḃ    Take the parity of that length
      =   Return 0 if unequal, 1 if equal to:
       V    the value of {the input} when eval'ed as a niladic Jelly program

อันดับแรกโปรดทราบว่าเนื่องจากอินพุตประกอบด้วยตัวเลขบางส่วน!ตามด้วยตัวเลขตามด้วยตัวเลขมากกว่า!นั้นหากเราลบการติดตาม!และใช้ความยาวเราจะลงท้ายด้วยหนึ่งบวกจำนวนผู้นำ!ในโปรแกรม การพาริตี้ของสิ่งนี้จะคืนค่า 0 ถ้ามีจำนวนคี่!หรือ 1 ถ้ามีจำนวน!คู่ การเปรียบเทียบกับ 0 คือฟังก์ชัน "ไม่" ในขณะที่การเปรียบเทียบกับ 1 คือฟังก์ชันตัวตน ดังนั้นจึงœr”!LḂ=มีประสิทธิภาพใช้ส่วน "รักษานำ!ในฐานะผู้ประกอบการไม่" ของคำถาม

ในช่วงครึ่งปีหลังการจัดการแฟ็กทอเรียล!เป็นการดำเนินการแฟกทอเรียลในเยลลี่ดังนั้นหากโปรแกรมไม่มีผู้นำ!เราสามารถแก้ปัญหาได้โดยตรงด้วยวิธีง่ายๆeval( V) หากโปรแกรมไม่ได้นำ!เหล่านั้นจะถูกตีความว่าเป็นปัจจัยที่เกิดจาก 0 (อาจจะหลายครั้ง), การผลิตที่มีมูลค่าการกลับมาของ 1 ซึ่งจะถูกพิมพ์ออกมาตรฐานและทิ้งครั้งหนึ่งเคยเป็นหลักคือการเห็น ดังนั้นพวกเขาไม่มีผลกระทบต่อมูลค่าส่งคืนของฟังก์ชั่นที่ฉันส่งคำถาม


คำอธิบายที่ดีและดีมาก
ElPedro

4

Python ขนาด 38 ไบต์

lambda s:(s[1::2]>s[::2])^ord(s[-1])%2

TryItOnline!

ไม่มีชื่อฟังก์ชั่นการสตริงการป้อนข้อมูลsและกลับมาเป็นจำนวนเต็มหรือ01

s[1::2] เป็นส่วนหนึ่งของสตริงอินพุตที่เริ่มต้นที่ดัชนี 1 และมีขนาดขั้นตอนที่สอง:
'Like this' -> 'ieti'

s[::2] คล้ายกัน แต่เริ่มต้นที่ดัชนีเริ่มต้นของ 0:
'Like this' -> 'Lk hs'

การทดสอบ(s[1::2]>s[::2])ตรวจสอบว่าดัชนี 0-based ของ'0'หรือ'1'เป็นคี่ว่าถ้าเราจำเป็นต้องเติมเต็ม
งานนี้เพราะการสั่งซื้อของสตริงมีการตรวจสอบ lexicographically กับสตริงไม่ว่างเปล่ามากกว่าสตริงที่ว่างเปล่าและมีการสั่งซื้อ ASCII '1'>'0'>'!'ดังนั้น s.index(max(s))%2นี่คือไบต์สั้นกว่าที่เรียบง่าย

การord(s[-1])%2ตรวจสอบเพื่อดูว่าอักขระตัวสุดท้ายไม่ใช่'0'(สำหรับอินพุตที่ถูกต้อง) และผลลัพธ์เป็นจำนวนเต็มหรือไม่ (ในขณะที่ความยาวเดียวกัน(s[-1]!='0')จะส่งกลับบูลีน)
สิ่งนี้ใช้งานได้เพราะอักขระตัวสุดท้ายของอินพุต, s[-1]จะเป็น'0',, '1'หรือ'!'ซึ่งมีรหัส ASCII ชี้ 48, 49, และ 33 ตามลำดับซึ่งคือ 0, 1 และ 1 โมดูโล 2

^แล้วดำเนินการบิตพิเศษหรือการดำเนินการเกี่ยวกับค่าที่สองข้างต้นกลับเป็นจำนวนเต็มตั้งแต่หนึ่งอินพุตขวาหนึ่งเป็นจำนวนเต็ม ถ้าด้านซ้ายเป็นจริงส่วนประกอบทั้งหมดของสิทธิจะถูกส่งคืนถ้าด้านซ้ายเป็นเท็จจะส่งคืนสิทธิตามความจำเป็น


4

Java 7, 105 82 81 ไบต์

int a(char[]a){int b=0,c=0;for(;a[b++]<34;c^=1);return(b<a.length?1:a[b-1]&1)^c;}

ลองออนไลน์!

โซลูชัน regex-ish แบบเก่า

int a(String a){a=a.replace("0!","1").replaceAll("1.*","1");int b=a.length()-1;return b%2^a.charAt(b)&1;}

2
c^=1ฉลาดสุด ๆ นั่นคือโอเปอเรเตอร์ที่ไม่ได้ใช้งานหากฉันเคยเห็น
Addison Crump

3

CJam , 12 11 ไบต์

r_W='0=!\~;

ลองออนไลน์! ชุดทดสอบ (พิมพ์ a 1สำหรับแต่ละกรณีทดสอบที่ถูกต้อง)

r      e# Read input.
_W='0= e# Duplicate and check whether the string ends in '0'. This is the
       e# only case in which the factorial part results in 0.
!      e# Negate this to get the actual result of the factorial part.
\      e# Swap with the input.
~      e# Evalute the input as CJam code. The leading `!` will apply the logical
       e# negations to the factorial result. The 0 or 1 will then push a junk value
       e# which is potentially negated a few times as well, by the factorials.
;      e# Discard the junk value.


3

Brainfuck, 115 ไบต์

>,[->++++[<-------->-]<[--------------->,[<[-]+>-]<<[->-[>+<+]>[-<+>]<<]>>++++++[-<++++++++>]<.>>+<]>-[<<+>,>[-]]<]

ลองออนไลน์!

Ungolfed:

% 0: inverter count
% 1: result
% 2: if/else flag; tmpspace in inner loop 0

>1,[
    ->2++++[<-------->-]<1 subtract 33 (!)
    [ 
        % we've reached the number
        ---------------
        % now it's either 0 or 1

        % check next char; If it's not 0 then it's '!'
        % 0! = 1! = 1!...! so we only need to determine if at least one ! exists
        >2,
                [<[-]+>-]<1

        % apply inversions
        <0
        [->1
            % invert cell 1 once each iteration
                       % cell 1 is 0 or 1
            -          % cell 1 is 255 or 1
            [>+<+]     % cell 1 is 0; cell 2 is 1 iff cell 1 should be 1
            >2[-<+>]<1 % cell 1 is 1 or 0
        <0]

        % print result
        >1>++++++[-<++++++++>]<1.

        >>2+< % tape={0 r 0 1}
    ]
    >2-[ % we haven't seen the number yet
        <<0+>1,>2 % add to inverter count
        [-]
    ]<1
]

2

แบตช์ 62 ไบต์

@set/ps=
@set s=%s:0!=1%
@set s=%s:!!=%
@cmd/cset/a%s:1!=1%

ใช้อินพุตบน STDIN แบทช์เข้าใจความจริงของการเป็นผู้นำ!อย่างถูกต้องสำหรับความท้าทายนี้ แต่ต้องใช้การติดตามต่อ!ไปซึ่งต้องใช้สามขั้นตอน:

  • เปลี่ยน0!เป็น1
  • ลบคู่ของ!!(ซึ่งปลอดภัยสำหรับ!!s ก่อนที่ตัวเลขจะมากเกินไป)
  • ลบการติดตามที่เหลืออยู่ใด ๆ!(ซึ่งตอนนี้สามารถอยู่หลังได้1)

2

สูตร IBM / Lotus Notes - 77 ไบต์

@Eval(@Left(a;@If(@Like(a;"%1%");"1";"0"))+@If(@Ends(a;"!");"1";@Right(a;1)))

ไม่มี TIO สำหรับสูตร Notes ดังนั้นภาพหน้าจอของกรณีทดสอบทั้งหมดแสดงไว้ด้านล่าง:

กรณีทดสอบทั้งหมด

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

@Eval() ประเมินสตริงเป็นนิพจน์

ก่อนอื่นเราจะตรวจสอบว่าสตริงอินพุตในฟิลด์ (อินพุต) aมี1หรือไม่0และนำอักขระทั้งหมดไปทางซ้ายไม่ว่าจะเป็นสตริง!ตัวไหน เราไม่สนใจว่าจะเป็นจำนวนเท่าใด @Eval()จะดูแลสิ่งนั้น

ต่อไปเราจะดูว่ามี!จุดสิ้นสุดของสตริงหรือไม่ หากมีเราผนวก1กับ!สตริง ( 0!และ1!มีทั้งที่ 1 - มันไม่สำคัญว่าหลาย!ตัวละครมีที่สิ้นสุด) มิฉะนั้นเราผนวกตัวอักษรตัวสุดท้ายไม่เปลี่ยนแปลงเพราะมันไม่ได้เป็น!และจะเป็นอย่างใดอย่างหนึ่งหรือ10

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


2

sed, 36 33 31 ไบต์

sed ที่บริสุทธิ์ไม่มี utc bc / shell ทำงานบน GNU sed <4.3; 33 ไบต์บน BSD และ GNU 4.3+

s/.!!*$/1/
:
s/!0/1/
s/!1/0/
t

ตรงไปตรงมาพอถ้าคุณคุ้นเคยกับsed; แสดงความคิดเห็นสำหรับผู้ที่ไม่ได้:

# Since 0! == 1! == 1 and factorial has precedence, just collapse any trailing "!" 
s/.!!*$/1/
# Define an anonymous label
:
# Invert 0 if needed
s/!0/1/
# Invert 1 if needed
s/!1/0/
# If a change was made, go back to the anonymous label.
t

ทดสอบ:

% cat 109248.sed
s/.!!*$/1/
:l
s/!0/1/
s/!1/0/
tl
% wc -c 109248.sed
      33 109248.sed
% cat cases
0
1
0!
1!
!0
!1
!0!
!1!
0!!
1!!
!!0
!!1
!0!!
!!!1
!!!0!!!!
!!!1!!!!
% sed -f 109248.sed cases
0
1
1
1
1
0
0
0
1
1
0
1
0
0
0
0
% gsed -f 109248.sed cases
0
1
1
1
1
0
0
0
1
1
0
1
0
0
0
0
%

IIRC บางรุ่น (ทั้งหมด?) sedอนุญาตให้คุณใช้สตริง Null เป็นชื่อป้ายกำกับ หากคุณสามารถทำงานได้ที่นี่มันจะช่วยให้คุณประหยัดสองไบต์ จริงๆแล้วฉันไม่แน่ใจว่าจำเป็นต้องใช้ฉลากหรือไม่ ถ้าฉันไม่ได้พลาดอะไรบรรทัดแรกคือ idempotent ดังนั้นคุณอาจจะสามารถย้อนกลับไปที่จุดเริ่มต้นของโปรแกรมได้แทนที่จะต้องใช้ป้ายกำกับ

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

sed ของ GNU อนุญาตให้ใช้ป้ายกำกับเป็นเพียง:(ข้อผิดพลาดที่นำมาเป็นคุณลักษณะ) ซึ่งในกรณีนี้ทั้งสองtและb! คำสั่งข้ามไปยังตำแหน่งของฉลาก นอกจากนี้รหัส sed ต้องทำงานกับรุ่นอย่างน้อยหนึ่งรุ่นเช่นเดียวกับภาษาอื่นดังนั้นคุณไม่จำเป็นต้องสร้างรหัสที่ใช้งานได้กับ BSD เช่นกัน
seshoumara

2

PHP 7.1, 58 55 54 37 35 ไบต์

หมายเหตุ: ใช้การเข้ารหัส IBM-850

echo!!$argn[-1]^strspn($argn,~Ì)%2;

ทำงานแบบนี้:

echo '!!!0!!!!' | php -nR 'echo!!$argn[-1]^strspn($argn,~Ì)%2;';echo
> 0

คำอธิบาย

echo
  strspn($a=$argv[1],~Ì) # Count the number of leading exclamation marks.
  % 2                    # Make 0 (even) or 1 (odd).
  ^ !!$a[-1];            # Negate with factorial part (truthy value of the 
                         # last char):
                         # - "0" is considered falsy.
                         # - "1" or "!" is considered truthy.

การปรับแต่ง

  • บันทึก 3 ไบต์โดยใช้การเข้ารหัส IBM-850
  • บันทึกไบต์โดยเปลี่ยน regex เล็กน้อย
  • บันทึกแล้ว 17 ไบต์เวอร์ชันใหม่ที่ไม่มีชื่อฟังก์ชันยาวและกลับมา
  • บันทึก 2 ไบต์โดยใช้-R(ซึ่งทำให้$argnมี)

1

ถั่วขนาด 24 ไบต์

hexdump:

00000000 26 4a c1 53 a0 17 53 d0 80 a0 5d 20 80 0a a1 80  &JÁS .SÐ. ] ..¡.
00000010 81 00 25 3a ae a1 ab 24                          ..%:®¡«$
00000018

JavaScript ที่เทียบเท่า:

+eval(a.replace(/.!+$/,1))

ขออภัยเหยียบลงไปบนเท้าของคุณArnauld

คำอธิบาย:

ใช้บรรทัดแรกของอินพุตเป็นสตริงที่ยังไม่ฟอร์แมตaและแทนที่ตัวเลขใด ๆ ตามด้วยหนึ่งหรือมากกว่า!ด้วย1ดังนั้นส่วนที่เหลือสามารถเป็นeval'd โดย JavaScript

ลองตัวอย่างหรือชุดทดสอบ

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