ถอดรหัสสัญลักษณ์ทางคณิตศาสตร์


13

หากคุณได้อ่านหนังสือติดต่อโดยคาร์ลเซแกนความท้าทายนี้อาจดูคุ้นเคยสำหรับคุณ


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

สมการอินพุตแต่ละรายการจะประกอบด้วย

  • จำนวนเต็มที่ไม่เป็นลบ
  • อย่างใดอย่างหนึ่งของตัวอักษรA, B, CหรือD
  • จำนวนเต็มอื่นที่ไม่ใช่ลบ
  • บทบาท =
  • จำนวนเต็มที่ไม่ใช่ลบขั้นสุดท้าย

ตัดแบ่งกัน ตัวอย่างเช่นอินพุตที่เป็นไปได้คือ1A2=3ซึ่งคุณสามารถอนุมานได้ว่าAเป็นสิ่งที่เพิ่มเข้ามา 0 ≤ x ≤ 1,000แต่ละจำนวนเต็มจะตอบสนอง

อย่างไรก็ตามมันไม่ง่ายอย่างที่คิด เป็นไปได้ที่จะมีความกำกวมระหว่าง:

  • 5A0=5: การเพิ่ม / การลบ
  • 1A1=1: การคูณ / การหาร
  • 0A5=0: การคูณ / การหาร
  • 2A2=4: การเพิ่ม / การคูณ
  • 4A2=2: การลบ / การหาร
  • 0A0=0: การเพิ่ม / การลบ / การคูณ

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

ตัวอย่างเช่นสมมติว่าอินพุตเป็นสมการต่อไปนี้:

  • 0A0=0: นี่จะแคบลงเพื่อบวกการลบหรือการคูณ (ไม่สามารถหารด้วย 0)
  • 10B0=10: B ต้องเป็นการบวกหรือลบ
  • 5C5=10: C เป็นการเพิ่มที่เห็นได้ชัดซึ่งทำให้การลบ B ซึ่งทำให้การคูณ A

ดังนั้นการส่งออกสำหรับสมการป้อนข้อมูลเหล่านี้ควรจะตรงAกับ*, B ด้วย-และมีC+

อินพุตอาจถูกกำหนดเป็นสตริง whitespace- / comma-delimited เดี่ยวหรืออาเรย์ของสตริงแต่ละอันแทนสมการหนึ่ง เอาต์พุตอาจเป็นสตริงเดี่ยว ( "A*B-C+"), อาเรย์ ( ["A*", "B-", "C+"]) หรืออาเรย์สองมิติ / พจนานุกรม / dict-like ( {"A": "*", ...}หรือ[["A", "*"], ...])

คุณอาจคิดว่าตัวเลขจะไม่ถูกหารด้วยจำนวนอื่นที่ไม่หารด้วย (ดังนั้นคุณไม่ต้องกังวลว่าการหารควรเป็นทศนิยมหรือตัดปลาย)

เนื่องจากนี่คือรหัสที่สั้นที่สุดเป็นไบต์จะเป็นผู้ชนะ

กรณีทดสอบ:

In                       Out
-------------------------------
0A0=0 10B0=10 5C5=10     A*B-C+
100D100=10000            D*
4A2=2 4B2=2 0A0=0        A-B/
15A0=15 4B2=2 2C2=0      A+B/C-
1A1=1 0A0=0              A*
0A0=0 2A2=4 5B0=5 2B2=4  A*B+
2A2=4 0C0=0 5B0=5 5A0=5  A+B-C*
0A1000=0 4A2=2           A/

1
พวกเรากำลังทำหารจำนวนเต็ม (ตัด)?
Martin Ender

@ MartinBüttnerคุณสามารถสรุปได้ว่าจะไม่มีการหารด้วยจำนวนที่ไม่ส่งผลให้มีจำนวนเต็ม (แก้ไขเป็นคำถาม)
Doorknob

เราสามารถส่งออกเป็นพจนานุกรมได้หรือไม่
lirtosiast

@ThomasKwa แน่นอนว่าพจนานุกรมก็เป็นที่ยอมรับเช่นกัน
Doorknob

ตัวอย่างส่วนใหญ่ไม่สอดคล้องกับ " มันจะเป็นไปได้เสมอที่จะระบุอย่างชัดเจนโดยไม่ซ้ำกันว่าจดหมายฉบับใดที่เป็นตัวดำเนินการ " แม้ว่าพวกเขาจะสอดคล้องกับ " มันจะเป็นไปได้ที่จะระบุว่าตัวดำเนินการใด อินพุต "
Peter Taylor

คำตอบ:


9

MATL , 53 ไบต์

j61tthYX'+-*/'X{Y@!"t'ABCD'!XKX{@YXU?K@Y}hwxKGm1L3$).

ใช้รุ่นปัจจุบัน (10.1.0)

แก้ไข (12 มิถุนายน 2016): เพื่อปรับให้เข้ากับการเปลี่ยนแปลงในภาษาแทนที่Y}โดยgและโดย1L3$) Y)ลิงค์ด้านล่างรวมเอาการดัดแปลงเหล่านั้น

ลองออนไลน์!

คำอธิบาย

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

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

วิธีแก้ปัญหาที่พบจะกำหนดตัวดำเนินการให้กับตัวอักษรสี่ตัว แต่ไม่จำเป็นต้องปรากฏในอินพุต ดังนั้นการทดสอบขั้นสุดท้ายจะทำเพื่อยกเลิกการไม่ใช้ตัวอักษร (และตัวดำเนินการที่ตรงกัน)

j            % input data string
61           % '=' (ASCII)
tth          % duplicate twice and concat: '==' (ASCII)
YX           % regexprep to change '=' into '==' in input string
'+-*/'       % push string
X{           % transform into cell array {'+','-','*','/'}
Y@!          % all permutations, each in a column
"            % "for" loop. Iterate columns (that is, permutations)
  t          %   duplicate data string containing '=='
  'ABCD'!XK  %   create column array ['A';'B';'C';'D'] and copy to clipboard K
  X{         %   transform into column cell array {'A';'B';'C';'D'} 
  @          %   push column cell array with current permutation of operator symbols
  YX         %   regexprep. Replaces 'A',...,'D' with current permutation of operators
  U          %   convert to numbers, i.e. evaluate string
  ?          %   if all numbers are 1 (truthy result): found it! But before breaking...
    K        %     push column array ['A';'B';'C';'D']
    @Y}      %     push column array with current permutation of operator symbols
    h        %     concatenate horizontally into 4x2 char array
    wx       %     delete original input so it won't be displayed
    K        %     push ['A';'B';'C';'D']
    G        %     push input string
    m        %     logical index that tells which of 'A',...,'D' were in input string
    1L3$)    %     apply that index to select rows of the 4x2 char array
    .        %     we can now break "for" loop
             %   implicitly end "if"
             % implicitly end "for"
             % implicitly display stack contents

6

Python 278 ตัวอักษร

คำตอบแรกของฉันในการตีกอล์ฟ ...

มันเป็นเพียงฟังก์ชั่นที่ใช้อัลกอริทึมกำลังดุร้ายคุณเรียกมันว่าผ่านไปเป็นอาร์กิวเมนต์สตริงของสมการ

from itertools import *
def f(s):
    l=list("ABCD")
    for p in permutations("+-*/"):
        t=s
        for v,w in zip(l+["="," "],list(p)+["=="," and "]):
            t=t.replace(v, w)
        try:
            o=""
            if eval(t):
                for c,r in zip(l,p):
                    if c in s:
                        o+=c+r
                return o
        except:
            pass

ฉันไม่แน่ใจว่ามันใช้งานได้ แต่คุณสามารถแทนที่["A","B","C","D"]ด้วยได้list("ABCD")หรือไม่
Adnan

สิ่งที่ @Adnan ที่แนะนำทำงานได้จริง นอกจากนี้คุณยังสามารถลบช่องว่างที่อยู่รอบ ๆในความหมายของ= l
Alex A.

@Adnan และ Alex A. ขอบคุณฉันแก้ไขรหัส
Bob

นี่คือ 257 ไบต์สำหรับวิธีการเดียวกันรวมถึงสภาพแวดล้อมการทดสอบออนไลน์
Alex A.

ทำการเปลี่ยนแปลงบางอย่าง - repl.it/BfuU คุณสามารถลดจำนวนไบต์ได้มากขึ้นโดยเลือกรูปแบบผลลัพธ์อื่น โซลูชันนี้ใช้งานได้กับ python 3 btw ( 4A2=2 4B3=1) เท่านั้น
Nabb

4

JavaScript (ES6), 213 208 ไบต์

f=(l,s="+-*/",p="",r)=>s?[...s].map(o=>r=f(l,s[g="replace"](o,""),p+o)||r)&&r:l.split` `.every(x=>(q=x.split`=`)[1]==eval(q[0][g](/[A-D]/g,m=>p[(a="ABCD").search(m)])))&&a[g](/./g,(c,i)=>l.match(c)?c+p[i]:"")

คำอธิบาย

อินพุตและเอาต์พุตเป็นสตริง

กำหนดฟังก์ชั่นfซึ่งคู่เป็นฟังก์ชั่นสำหรับการสร้าง recursive evalพีชคณิตทั้งหมดของผู้ประกอบการและการทดสอบพีชคณิตสมบูรณ์ด้วยสมการป้อนข้อมูลโดยใช้

f=(
  l,                          // l = input expression string
  s="+-*/",                   // s = remaining operators
  p="",                       // p = current permutation of operators
  r                           // r is here so it is defined locally
)=>
  s?                          // if there are remaining operators
    [...s].map(o=>            // add each operator o
      r=f(
        l,
        s[g="replace"](o,""), // remove it from the list of remaining operators
        p+o                   // add it to the permutation
      )
        ||r                   // r = the output of any permutation (if it has output)
    )
    &&r                       // return r
  :                           // else if there are no remaining operators
    l.split` `.every(x=>      // for each expression
      (q=x.split`=`)          // q = [ equation, result ]
      [1]==eval(              // if the results is equal to the eval result

        // Replace each letter with the current permutation
        q[0][g](/[A-D]/g,m=>p[(a="ABCD").search(m)])
      )
    )

    // If all results matched, add permutation symbols to present characters and return
    &&a[g](/./g,(c,i)=>l.match(c)?c+p[i]:"")

ทดสอบ

การทดสอบไม่ได้ใช้อาร์กิวเมนต์เริ่มต้นสำหรับความเข้ากันได้ของเบราว์เซอร์

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