การประเมิน Dotty Strings


25

จงเขียนโปรแกรมที่ใช้ในสตริงที่มีความยาวแปลกที่มีเพียงตัวละครและ. :ด้วยความช่วยเหลือของกองซ้อนที่ว่างเปล่าเริ่มสร้างหมายเลขจากสายอักขระนี้ดังนี้:

ทุกตัวอักษรCในสตริง (ไปจากซ้ายไปขวา) ...

  • หากcคือ.และสแต็กมีองค์ประกอบน้อยกว่า 2 ให้กด 1 บนสแต็ก
  • หากcคือ.และสแต็กมี 2 องค์ประกอบหรือมากกว่าให้ปรากฏค่าสูงสุดสองค่าออกจากสแต็กและส่งผลรวมของพวกเขาไปยังสแต็ก
  • หากcคือ:และสแต็กมีองค์ประกอบน้อยกว่า 2 ให้กด 2 บนสแต็ก
  • หากcคือ:และสแต็กมีองค์ประกอบ 2 ตัวหรือมากกว่าให้แสดงค่าสูงสุดสองค่าออกจากสแต็กและดันผลิตภัณฑ์ลงบนสแต็ก

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

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

ตัวอย่างเช่นหมายเลขสำหรับ::...:.:.คือ 9:

  2   1   2   2    /______ stack just after the character below is handled
2 2 4 4 5 5 7 7 9  \
: : . . . : . : .  <-- string, one character at a time

ในฐานะที่เป็นสติตรวจสอบที่นี่เป็นตัวเลขสำหรับทุกสายยาว 1, 3 และ 5:

. 1
: 2
... 2
..: 1
.:. 3
.:: 2
:.. 3
:.: 2
::. 4
::: 4
..... 3
....: 2
...:. 4
...:: 4
..:.. 2
..:.: 1
..::. 3
..::: 2
.:... 4
.:..: 3
.:.:. 5
.:.:: 6
.::.. 3
.::.: 2
.:::. 4
.:::: 4
:.... 4
:...: 3
:..:. 5
:..:: 6
:.:.. 3
:.:.: 2
:.::. 4
:.::: 4
::... 5
::..: 4
::.:. 6
::.:: 8
:::.. 5
:::.: 4
::::. 6
::::: 8

โปรแกรมที่สั้นที่สุดในหน่วยไบต์ชนะ Tiebreaker เป็นโพสต์ก่อนหน้า

  • คุณอาจสันนิษฐานว่าอินพุตนั้นถูกต้องเสมอเช่นสตริงที่มีเพียง.และ:มีความยาวคี่
  • แทนที่จะเขียนโปรแกรมคุณสามารถเขียนฟังก์ชั่นที่รับสายอักขระที่ถูกต้องและพิมพ์หรือส่งกลับหมายเลขที่สร้างขึ้น

5
อีควอไลเซอร์ที่เรียบง่ายที่สุดเท่าที่เคยมีมา
dberm22

คำตอบ:


13

CJam, 27 24 23 22 bytes

q{i]_,+~3<-"1+2* "=~}/

ตรงไปตรงมาสวย ฉันใช้สแต็คของ CJam เป็นสแต็คที่กล่าวถึงในคำถาม;)

ขั้นตอนวิธี

แรกให้ดูที่รหัส ASCII สำหรับและ.:

'.i ':ied

[46 58]

ตั้งแต่ใน CJam ดัชนีจะล้อมรอบลองดูว่าเราสามารถใช้ค่าเหล่านี้โดยตรงเพื่อให้ได้การทำงานที่ต้องการ ..

'.i4% ':i4%ed

[2 2]

ดังนั้นฉันไม่สามารถใช้รหัส ASCII ในสตริงการดำเนินการความยาว 4 ตัวได้อย่างง่ายดาย ให้ลองใช้ค่าอื่น ๆ

'.i 10% ':i 10%ed

[6 8]

ซึ่งบนความยาว 4 สตริงเดือดลงไป

[2 0]

ฉันสามารถใช้การทำงานของ mod 10 นี้ได้ แต่จะมีราคา 2 ไบต์ ให้ลองอย่างอื่น

'.i5% ':i5%ed

[1 3]

ดีมากตอนนี้เราเพิ่งลบ 1 สำหรับเงื่อนไขขนาดสแต็กเพื่อรับดัชนี0, 1, 2 and 3และใช้5อาร์เรย์ความยาว ( "1+2* ") เป็นตัวเรือนสวิตช์ พื้นที่สุดท้ายเป็นเพียงฟิลเลอร์เพื่อให้มีความยาว 5 นี่เป็นเพียง 1 ไบต์พิเศษเมื่อเทียบกับการดำเนินการ modding

q{                  }/    e# parse each input character in this loop
  i]                      e# convert '. or ': into ASCII code and wrap everything
                          e# in stack in an array
    _,+                   e# Copy the stack array, take its length and add the length to
                          e# the stack array 
       ~3<                e# unwrap the stack array and check if stack size is less than 3
                          e# 3 because either . or : is also on stack
          -               e# subtract 0 or 1 based on above condition from ASCII code
           "1+2* "        e# string containing the operation to perform
                  =~      e# chose the correct operation and evaluate it

ลองออนไลน์ได้ที่นี่

บันทึก 1 ไบต์ต้องขอบคุณcosechy


1
พื้นที่สำหรับสายอักขระของการดำเนินการคืออะไร
Peter Taylor

@PeterTaylor อธิบายในโพสต์
เครื่องมือเพิ่มประสิทธิภาพ

9

> <> (ปลา) 33 ไบต์

ib%1-i:1+?\~n;
5a*)?*+40.\b%1-0@i

ค่อนข้างตรงไปตรงมาด้วยเทคนิค / การปรับแต่งเล็กน้อย

คำอธิบาย:

  • ข้อมูล: icodepoint ของอินพุตถ่านตัวต่อไป-1ถ้าถึงจุดสิ้นสุดของอินพุต a= 10; b= 11; )=>
  • icodepoint ของถ่านอินพุตแรก
  • b%1- top_of_stack mod 11 - 1หน้ากาก48 ('.') , 56 (':')เพื่อ1 , 2
  • i:1+?\~n; หากถึงจุดสิ้นสุดของอินพุตให้พิมพ์ผลลัพธ์สุดท้ายและยุติ
  • มิฉะนั้น:
  • b%1- รูปแบบการป้อนข้อมูลให้กับ 1 , 2
  • 0@กด0ใต้เลขสองตัว
  • i5a*)อ่านอินพุตถัดไปและซ่อนไว้เพื่อ0 , 1เปรียบเทียบกับ50
  • ถ้า1( ':') คูณสององค์ประกอบบนสุดสร้างสแต็ก [0 ผลิตภัณฑ์]
  • เพิ่มองค์ประกอบสองอันดับแรกที่สร้างกอง[0 sum]หรือ[0+product=product]
  • 40.กระโดด (วง) กลับไปที่ตำแหน่ง(4,0)ชี้ของเรา4,i:1+?\~n;

8

Haskell, 73 65 ไบต์

ทางออกที่ตรงไปตรงมาโดยใช้ความจริงที่ว่าสแต็คไม่เคยมีมากกว่า 2 องค์ประกอบ

[x,y]#'.'=[x+y]
[x,y]#_=[x*y]
s#'.'=1:s
s#_=2:s
f=head.foldl(#)[]

5

C, 104 ไบต์

k[2],n;f(char*c){for(n=0;*c;)k[n]=*c++-58?n>1?n=0,*k+k[1]:1:n>1?n=0,*k*k[1]:2,k[1]=n++?k[1]:0;return*k;}

นี่มันยาวเกินไป


5

Pyth, 25 24 ไบต์

eu?]?.xGHsGtG+GhHmqd\:zY

มีความคิดโดยศึกษาวิธีการแก้ปัญหาของ @ isaacg แต่ฉันใช้สแต็ค

การสาธิตออนไลน์หรือชุดทดสอบ

คำอธิบาย

สิ่งแรกที่ฉันทำคือการแปลงสตริงอินพุตเป็น 0s และ 1s "."ได้รับการดัดแปลงให้เป็น0ที่เป็น":"1

mqd\:z   map each char d of input to (d == ":")

จากนั้นฉันลดรายการตัวเลขนี้:

eu?]?.xGHsGtG+GhHmqd\:zY
 u                     Y   start with the empty stack G = []
                           for each H in (list of 0s and 1s), update G:
                              G = 
    ?.xGHsG                      product of G if H != 0 else sum of G
   ]                             wrapped in a list 
  ?        tG                 if G has more than 1 element else
             +GhH                G + (H + 1)
e                         take the top element of the stack

4

JavaScript (ES6), 65

เราใช้ 2 เซลล์ของสแต็กของเราเท่านั้น

เริ่มวางค่าใน s [0]
จากนั้นในแต่ละตำแหน่งคี่ (นับจาก 0) ในสตริงอินพุตให้ใส่ค่าใน s [1]
ในแต่ละตำแหน่งให้ทำการคำนวณแคลคูลัส (เพิ่มหรือทวีคูณ) และเก็บผลลัพธ์เป็น s [0]

ดังนั้นลืมเกี่ยวกับสแต็กและใช้เพียง 2 ตัวแปรคือ a และ b

f=s=>[...s].map((c,i)=>(c=c>'.',i&1?b=1+c:i?c?a*=b:a+=b:a=1+c))|a

การทดสอบอย่างรวดเร็ว

for(i=0;i<128;i++)
{
  b=i.toString(2).replace(/./g,v=>'.:'[v]).slice(1)
  if(b.length&1) console.log(b,f(b))
} 

เอาท์พุต

"." 1
":" 2
"..." 2
"..:" 1
".:." 3
".::" 2
":.." 3
":.:" 2
"::." 4
":::" 4
"....." 3
"....:" 2
"...:." 4
"...::" 4
"..:.." 2
"..:.:" 1
"..::." 3
"..:::" 2
".:..." 4
".:..:" 3
".:.:." 5
".:.::" 6
".::.." 3
".::.:" 2
".:::." 4
".::::" 4
":...." 4
":...:" 3
":..:." 5
":..::" 6
":.:.." 3
":.:.:" 2
":.::." 4
":.:::" 4
"::..." 5
"::..:" 4
"::.:." 6
"::.::" 8
":::.." 5
":::.:" 4
"::::." 6
":::::" 8

-2:f=s=>[(c=s[i]>'.',i&1?b=1+c:+i?c?a*=b:a+=b:a=1+c)for(i in s)]|a
ขีดล่าง

@ น้อยกว่าอย่างน้อยใน borwser ของฉันที่ไม่ทำงาน สำหรับ (ฉันใน) ให้คุณสมบัติพิเศษนอกเหนือจากดัชนี
edc65

มันใช้งานได้สำหรับฉันใน firefox 37.0.2 ลองใช้ในแท็บเบราว์เซอร์ที่สะอาด ดูเหมือน stackexchange จะเพิ่มคุณสมบัติเพิ่มเติมให้กับสตริง (ใน stub.en.js)
nderscore

3

Pyth, 27 ไบต์

Jmhqd\:zu?*GhHteH+GhHctJ2hJ

สแต็ค? ต้องการสแต็คใคร

                       Implicit: z is the input string.
Jmhqd\:z               Transform the string into a list, 1 for . and 2 for :
                       Store it in J.
u            ctJ2hJ     Reduce over pairs of numbers in J, with the
                       first entry as initial value.
 ?    teH               Condition on whether the second number is 1 or 2.
  *GhH                  If 1, update running total to prior total times 1st num.
         +GhH           If 2, update running total to prior total plus 1nd num.

สาธิต.


1
อัจฉริยภาพ และในขณะเดียวกันฉันก็ใช้สแต็ก (32 ไบต์) :-(
Jakube

3

Retina , 105 75 73 ไบต์

โปรแกรม Retina ครั้งแรกของฉัน! (ขอบคุณ Martin Büttnerสำหรับการบันทึก 2 ไบต์ไม่ต้องพูดถึงการประดิษฐ์ภาษาในตอนแรก)

แต่ละบรรทัดควรไปในไฟล์แยกกัน หรือคุณสามารถวางทั้งหมดไว้ในไฟล์เดียวและใช้-sแฟล็ก <empty>สัญกรณ์หมายถึงไฟล์ที่ว่างเปล่า / บรรทัด

^(a+;)?\.
$1a;
^(a+;)?:
$1aa;
;(a+;)\.
$1
(a+);aa;:
$1$1;
)`;a;:
;
;
<empty>
a
1

แรงบันดาลใจจากคำตอบของ mbomb007แต่ฉันใช้แนวทางที่แตกต่างออกไป ความแตกต่างที่สำคัญอย่างหนึ่งคือฉันสร้างสแต็กหน้าสตริง dotty (โดยที่ด้านบนของสแต็กหันไปทางขวา) สิ่งนี้ทำให้ง่ายต่อการแปลงสัญลักษณ์เป็นหมายเลขที่ตรงกัน ฉันยังใช้aแทน1, สลับมันตอนท้ายเท่านั้น, เพื่อหลีกเลี่ยงการวิเคราะห์ความกำกวมในลำดับ$1aดังนี้ หากคำตอบที่ต้องการaaaaaaนั้นสามารถยอมรับได้ในรูปแบบเลขคู่สามารถแยกบรรทัด / ไฟล์สองบรรทัดสุดท้ายออกเพื่อบันทึก 4 ไบต์

คำอธิบาย:

^(a+;)?\.
$1a;

จับคู่ถ้ามี 0 หรือ 1 รายการในสแต็ก ( (a+;)?) ตามด้วยจุด ( \.); ถ้าเป็นเช่นนั้นจะแทนที่ระยะเวลาด้วยa;(เช่นกด 1)

^(a+;)?:(.*)
$1aa;$2

จับคู่หากมี 0 หรือ 1 รายการในสแต็กตามด้วยโคลอน หากเป็นเช่นนั้นจะแทนที่โคลอนด้วยaa;(เช่นกด 2)

;(a+;)\.
$1

จับคู่หากมีสองรายการในสแต็กตามด้วยจุด ลบจุดและเครื่องหมายอัฒภาคระหว่างรายการจึงเพิ่ม

(a+);aa;:
$1$1;

จับคู่ถ้ามีสองไอเท็มบนสแต็กด้านบนของไอเท็มคือ 2 ตามด้วยโคลอน ลบเครื่องหมายโคลอนและ 2 และทำซ้ำหมายเลขอื่นสองครั้งจึงคูณด้วย 2

)`;a;:
;

regex ตรงกันหากมีสองรายการในสแต็กด้านบนซึ่งเป็น 1 ตามด้วยเครื่องหมายโคลอน ลบเครื่องหมายโคลอนและ 1 ออกจากหมายเลขอื่นที่ไม่เปลี่ยนแปลง (เช่นคูณด้วย 1)

)`หมายถึงจุดสิ้นสุดของลูป หากมีการเปลี่ยนแปลงใด ๆ กับสตริงการควบคุมจะกลับไปที่ด้านบนของโปรแกรมและเรียกใช้การแทนที่อีกครั้ง หากสตริงหยุดการเปลี่ยนแปลงเราจะแทนที่ช่วงเวลาและโคลอนทั้งหมดและสิ่งที่เหลืออยู่คือการล้างข้อมูล ...

;
<empty>

ลบเซมิโคลอนที่เหลือ

a
1

แปลง a ทั้งหมดให้เป็น 1 อีกครั้งหากอนุญาตให้ใช้หมายเลขใด ๆ ก็สามารถใช้สัญลักษณ์ใด ๆ ขั้นตอนนี้ไม่จำเป็น


การเริ่มต้นของลูปถือว่าเป็นไฟล์แรกหรือไม่?
mbomb007

@ mbomb007 ใช่ ฉันเคยเห็นว่าในเอกสาร แต่ลืมไปแล้วว่ามาร์ตินทำให้ฉันนึกถึงมัน ;)
DLosc

2

สนิม 170 ตัวอักษร

fn f(s:String)->i32{let(mut a,mut b)=(-1,-1);for c in s.chars(){if b!=-1{a=match c{'.'=>a+b,':'=>a*b,_=>0};b=-1}else{b=match c{'.'=>1,':'=>2,_=>0};if a==-1{a=b;b=-1}};}a}

หลักฐานเพิ่มเติมว่าสนิมนั้นแย่มากในการเล่นกอล์ฟ รหัส ungolfed เต็มรูปแบบ:

#[test]
fn it_works() {
    assert_eq!(dotty_ungolfed("::...:.:.".to_string()), 9);
    assert_eq!(f("::...:.:.".to_string()), 9);
}

fn dotty_ungolfed(program: String) -> i32 {
    let (mut a, mut b) = (-1, -1);
    for ch in program.chars() {
        if b != -1 {
            a = match ch { '.' => a + b, ':' => a * b, _ => panic!() };
            b = -1;
        } else {
            b = match ch { '.' => 1, ':' => 2, _ => panic!() };
            if a == -1 { a = b; b = -1; }
        }
    }
    a
}

fn f(s:String)->i32{let(mut a,mut b)=(-1,-1);for c in s.chars(){if b!=-1{a=match c{'.'=>a+b,':'=>a*b,_=>0};b=-1}else{b=match c{'.'=>1,':'=>2,_=>0};if a==-1{a=b;b=-1}};}a}

นี่คือเคล็ดลับที่น่าสนใจที่ฉันใช้ในอันนี้ คุณสามารถโกนอักขระในคำสั่ง if / else โดยให้พวกมันคืนค่าที่ถูกทิ้งในทันทีซึ่งหมายความว่าคุณต้องการเพียงหนึ่งอัฒภาคแทนที่จะเป็นสอง

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

if foo {
    a = 42;
} else {
    doSomething(b);
}

สามารถเปลี่ยนเป็น

if foo {
    a = 42
} else {
    doSomething(b)
};

ซึ่งบันทึกอักขระด้วยการโกนเซมิโคลอนออก


2

Haskell, 88 81 79 Bytes

(h:t)![p,q]|h=='.'=t![p+q]|1<2=t![p*q]
(h:t)!s|h=='.'=t!(1:s)|1<2=t!(2:s)
_!s=s

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


2

APL (50)

ฉันเสียเปรียบอย่างมากที่นี่เพราะ APL ไม่ใช่ภาษาสแต็ก ในที่สุดฉันก็ต้องลดการละเมิดเพื่อย่อโปรแกรมให้สั้นลง

{⊃{F←'.:'⍳⍺⋄2>⍴⍵:F,⍵⋄((⍎F⌷'+×')/2↑⍵),2↓⍵}/(⌽⍵),⊂⍬}

ฟังก์ชั่นด้านในใช้ 'คำสั่ง' ทางด้านซ้ายและสแต็คทางด้านขวาและนำไปใช้กับมันกลับกอง ฟังก์ชั่นด้านนอกลดความมันลงบนสตริงเริ่มต้นด้วยสแต็กเปล่า

คำอธิบาย:

  • (⌽⍵),⊂⍬: รายการเริ่มต้นเพื่อลด ⊂⍬เป็นรายการที่ว่างในกล่องซึ่งแสดงถึงสแต็ก(⌽⍵)คือด้านหลังของอินพุต (การลดจะใช้จากขวาไปซ้ายเหนือรายการดังนั้นสตริงจะถูกประมวลผลจากขวาไปซ้ายการย้อนกลับอินพุตล่วงหน้าทำให้มันใช้อักขระตามลำดับที่ถูกต้อง)

  • {... }: ฟังก์ชั่นด้านใน มันใช้สแต็คทางด้านขวาอักขระทางด้านซ้ายและส่งคืนสแต็กที่แก้ไข

    • F←'.:'⍳⍺: ดัชนีของตัวละครในสตริง.:นี้จะเป็น 1 หรือ 2 ขึ้นอยู่กับค่า
    • 2>⍴⍵:F,⍵: หาก 2 มีขนาดใหญ่กว่าขนาดสแต็กปัจจุบันเพียงเพิ่มค่าปัจจุบันต่อท้ายสแต็ก
    • : มิฉะนั้น,
      • 2↓⍵: ลบสองรายการบนสุดออกจากสแต็ก
      • (... )/2↑⍵: ลดฟังก์ชั่นที่กำหนดไว้เหนือพวกมันและเพิ่มเข้าไปในสแต็ก
      • ⍎F⌷'+×': ฟังก์ชั่นเป็นอย่างใดอย่างหนึ่ง+(เพิ่มเติม) หรือ×(คูณ) Fเลือกโดย
  • : ในที่สุดให้ส่งคืนไอเท็มสูงสุดบนสแต็ก


2

Ruby - 96 ตัวอักษร

ชิ้นที่น่าสนใจ sorta evalที่นี่คือ

นอกเหนือจากนั้นฉันกำลังตั้งสมมติฐานว่าหลังจากตัวละครตัวแรกสแต็คจะไป 2, คณิตศาสตร์, 2, คณิตศาสตร์, .... สิ่งนี้ช่วยให้ฉันใช้รหัสน้อยลงโดยคว้าสองตัวอักษรพร้อมกัน - ฉันไม่ต้องคิด ไม่ว่าตัวละครจะเป็นเลขหรือเลข มันเป็นตำแหน่ง

x,m=$<.getc>?.?2:1
(b,f=m.split //
b=b>?.?2:1
x=f ?eval("x#{f>?.??*:?+}b"):b)while m=gets(2)
p x

Ungolfed:

bottom_of_stack = $<.getc > '.' ? 2 : 1 # if the first char is ., 1, else 2
two_dots = nil
while two_dots = gets(2) do # get the next 2 chars
  number_char, math_char = two_dots.split //
  number = number_char > '.' ? 2 : 1
  if math_char
    math = math_char > '.' ? '*' : '+'
    # so bottom_of_stack = bottom_of_stack + number ...
    # or bottom_of_stack = bottom_of_stack * number
    bottom_of_stack = eval("bottom_of_stack #{math} number")
  else
    # if there's no math_char, it means that we're done and 
    # number is the top of the stack
    # we're going to print bottom_of_stack, so let's just assign it here
    bottom_of_stack = number
  end
end
p bottom_of_stack  # always a number, so no need for `puts`

2

TI-BASIC, 78 73 70 69 66 ไบต์

Input Str1
int(e^(1=inString(Str1,":
For(A,2,length(Str1),2
Ans+sum({Ans-2,1,1,0},inString("::..:",sub(Str1,A,2
End
Ans

TI-BASIC ทำได้ดีที่หนึ่ง-liners เนื่องจากวงเล็บปิดเป็นตัวเลือก ในทางกลับกันมันเป็นภาษาที่ไม่ดีที่ต้องใช้การจัดเก็บค่าหลายค่าเนื่องจากการจัดเก็บตัวแปรใช้พื้นที่สองถึงสี่ไบต์ ดังนั้นเป้าหมายคือการเขียนมากที่สุดในแต่ละบรรทัดให้มากที่สุด TI-BASIC ยังเป็นที่น่ากลัว (สำหรับภาษา tokenized) ที่การจัดการสตริงทุกชนิด แม้การอ่านซับสตริงจะมีความยาว

เทคนิครวมถึง:

  • int(e^([boolean] แทน 1+(boolean ; บันทึกหนึ่งไบต์
  • ผลรวมบางส่วนของรายการแทนการแบ่งส่วนรายการ (ซึ่งจะต้องเก็บไว้ในรายการ): บันทึก 3 ไบต์

คุณควรใช้การป้อนข้อมูลจาก Ans เช่น".:.":prgmDOTTYการบันทึก 4 ไบต์
MI Wright

@Wright ฉันใช้ Ans เพื่อเก็บหมายเลขไว้ในสแต็ก
lirtosiast

ฉันหมายถึงจุดเริ่มต้น - กำจัดบรรทัดที่ 1 และเปลี่ยนบรรทัดที่สองเป็น1+(":"=sub(Ans,1,1
MI Wright

1
ฉันจำเป็นต้องใช้ Str1 ในลูปที่มีการใช้ Ans ดังนั้นฉันจึงไม่สามารถเก็บสายไว้ใน Ans ได้ การจัดเก็บไปที่ Str1 จาก Ans จะไม่ประหยัดพื้นที่ใด ๆ
lirtosiast

1

ไป, 129 115 112 ไบต์

func m(s string){a,b:=0,0;for c,r:=range s{c=int(r/58);if b>0{a=a*b*c+(a+b)*(c^1);b=0}else{b,a=a,c+1}};print(a)}

(ค่อนข้าง) ungolfed:

func m(s string){
    // Our "stack"
    a, b := 0, 0
    // abusing the index asignment for declaring c
    for c, r := range s {
        // Ascii : -> 58, we can now use bit fiddeling
        c = int(r / 58)
        if b > 0 {
            // if r is :, c will be 1 allowing a*b to pass through, c xor 1 will be 0
            // if r is ., c xor 1 will be 1 allowing a+b to pass through
            a = a*b*c + (a+b)*(c^1)
            b = 0
        } else {
            b, a = a, c+1 // Since we already know c is 0 or 1
        }
    }
    print(a)
}

ลองออนไลน์ได้ที่นี่: http://play.golang.org/p/B3GZonaG-y


1

Python 3, 74

x,*s=[1+(c>'.')for c in input()]
while s:a,b,*s=s;x=[x*a,x+a][-b]
print(x)

แรกเปลี่ยนรายการป้อนข้อมูลเป็นลำดับที่ 1 และ 2 xของการค่าแรกเป็นค่าเริ่มต้น จากนั้นถอดองค์ประกอบสองครั้งจากด้านหน้าsโดยรับหมายเลขแรกและเพิ่มหรือทวีคูณด้วยหมายเลขปัจจุบันโดยพิจารณาจากองค์ประกอบที่สองคือ 1 หรือ 2


1

อย่างนี้ใช้งานง่ายซับซ้อนโดย op (จงใจ)

มันเป็นเพียง ...

นิพจน์วงเล็บถูกแปลเป็นการดำเนินการ postfixed * / +

รหัส: C (80 ไบต์)

int f(char*V){return*(V-1)?f(V-2)*(*V==58?*(V-1)/29:1)+(*V&4)/4**(V-1)/29:*V/29;}
  • ควรเรียกใช้ฟังก์ชันนี้จากส่วนท้ายของสตริงดังนี้: f (V + 10) โดยที่ V = ".: .. :.: .. :: .. "

อินพุต

length = 2n + 1 vector V ของประเภท char '.' หรือ ':'

เอาท์พุต

จำนวนเต็ม k

ฟังก์ชัน

  • k = (V [1] op (V [3]) V [2]) op (V [5]) V [4] ....

  • op (x): (x = '.') -> +, (x = ':') -> *


จำลอง:

ลองที่นี่


คุณจะสมมติว่า byte ข้างหน้า string ( *(V-1)) เป็นศูนย์ได้อย่างไร?
nutki

เมื่อคุณจัดสรรเวกเตอร์ใหม่จุดเริ่มต้นของมันจะเริ่มจากเซ็กเมนต์ที่ว่างเปล่าเสมอและท้ายที่สุดมันจะเป็นตัวอักษรที่ว่างเปล่า
Abr001am

1

เรติน่า, 181 135 129 ไบต์

แต่ละบรรทัดควรอยู่ในไฟล์แยกต่างหาก <empty>แสดงถึงไฟล์ที่ว่างเปล่า เอาต์พุตอยู่ใน Unary

^\..*
$&1;
^:.*
$&11;
^.
<empty>
(`^\..*
$&1
^:.*
$&11
^.(.*?1+;1+)
$1
^(\..*);(1+)
$1$2;
;1$
;
^(:.*?)(1+).*
$1$2$2;
)`^.(.*?1+;)
$1
;
<empty>

เมื่อ${0}1มีการใช้งานเครื่องมือจัดฟันจะแยกออก$0จากกลุ่ม1มิฉะนั้นจะเป็น$01กลุ่มจับคู่ที่ 1 ฉันพยายามใช้$001แต่ดูเหมือนว่าจะไม่ทำงานใน. NET รสชาติของ regex

แก้ไข: พบว่าเป็นเช่นเดียวกับ$&$0

ในโค้ดหลอกสิ่งนี้จะเป็นลูป do-while อย่างที่เห็นด้านล่าง ฉันกดหมายเลขแรกจากนั้นวนซ้ำ: กดหมายเลขที่สองลบการดำเนินการ (คำสั่ง) ทำคณิตศาสตร์ลบ op ทำการวนซ้ำต่อไป โปรดทราบว่าเมื่อการดำเนินการถูกเปิดสิ่งนี้จะลบพื้นที่ออกหลังจากทำตามคำแนะนำทั้งหมด

แสดงความคิดเห็น:

^\..*           # Push if .
$&1;
^:.*            # Push if :
$&11;
^.              # Pop op
<empty>


(`^\..*         # Loop, Push #
$&1
^:.*
$&11
^.(.*?1+;1+)    # Pop op
$1


^(\..*);(1+)    # Add if . (move ;)
$1$2;
;1$          # If mul by 1, remove
;
^(:.*?)(1+).*   # Mul if : (double)
$1$2$2;
)`^.(.*?1+;)    # Pop op, End Loop (clean up)
$1
;               # Remove semicolon
<empty>

สิ่งสำคัญที่ฉันเห็นนักกอล์ฟคือรูปแบบ / คู่แทนเช่น(:)(.*)-> $1$2ซึ่งฉันค่อนข้างแน่ใจว่าจะเป็น(:.*)-> $1(เนื่องจากคุณรักษาทั้งสองกลุ่มไว้ในลำดับเดียวกันและไม่ทำอะไรกับพวกเขา )
DLosc

ฉันได้รับแรงบันดาลใจและทำคำตอบกับ Retina ของฉันเอง ขอบคุณที่ทำให้ฉันดาวน์โหลดภาษาที่น่าสนใจนี้!
DLosc

@DLosc ยอดเยี่ยม! ใช่ฉันยังไม่ได้ดาวน์โหลดมัน ฉันใช้เครื่องทดสอบแทนที่ regex ออนไลน์สำหรับการแทนที่แต่ละรายการ
mbomb007

0

Python 3, 122 ไบต์

x=input()
l=[0,0]
for _ in x:
 t=len(l)-2<2
 l=[[[0,0,l[-2]*l[-1]],l+[2]][t],[[0,0,sum(l)],l+[1]][t]][_=='.']
print(l[-1])

Ungolfed:

x = input()
l = []
for i in x:
    if i == '.':
        if len(l) < 2: 
            l+=[1]        #True, True = 1,1
        else:
            l=[sum(l)]    #True, True = 1,0
    else:
        if len(l)<2:
            l+=[2]        #False, True = 0,1
        else:
            l=[l[0]*l[1]] #False, False = 0,0
print (l[0])

ในหลาม, คุณอ้างอิงดัชนีของรายการเช่นนี้:

list[index]

คุณสามารถใส่ค่าบูลีนลงไปในนั้นTrueเป็น1และเป็นFalse0

# t is True if the length is less than 2, else false.

l=[ 

  # |------- Runs if char is : -------|
  # |------- l<2 -------| |- l>=2 -|

    [ [ 0,0, l[-2]*l[-1] ], l+[2] ] [t],

                                      # |---- Runs if char is . ----| 
                                      # |--- l<2 ---|  |- l>=2 -|

                                        [ [0,0, sum(l)], l+[1] ] [t] ]
                                                                      [_=='.']

ลองออนไลน์ได้ที่นี่


0

Perl 77 ไบต์

@o=(0,'+','*');sub d{$_=shift;y/.:/12/;eval'('x s!\B(.)(.)!"$o[$2]$1)"!ge.$_}

ขยาย:

@o=(0, '+', '*');
sub d{
    $_=shift;
    y/.:/12/;
    eval '(' x s!\B(.)(.)!"$o[$2]$1)"!ge.$_
}

@oอาร์เรย์แผนที่ตัวเลขกับผู้ประกอบการ แล้วเราแทนคู่ของตัวเลขกับผู้ประกอบการที่เหมาะสมในการจัดลำดับใหม่มัด regexp เริ่มต้นด้วย\Bดังนั้นเราจึงไม่ตรงกับตัวอักษรตัวแรกมาก ผลของการs///gบอกเราว่าต้องมีการเปิดล้อเลียนกี่ครั้งในตอนแรก จากนั้นเมื่อเราได้รวบรวมการแสดงออกมัดเต็มเราสามารถประเมิน (ลบevalหากคุณต้องการดูการแสดงออกแทน)

นี่คือสายรัดทดสอบที่ฉันใช้ตรวจสอบผลลัพธ์:

while(<>) {
    my ($a, $b) = m/(.*) (.*)/;
    print d($a), " $b\n";
}

อินพุตคือรายการของการแสดงออกของจุดและค่าของพวกเขา (ระบุไว้ในคำถาม) และเอาท์พุทเป็นคู่ของ {จริงคาดว่า}

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