ตัวนับคะแนนสำหรับ Skat


11

งานของคุณคือการเขียนโปรแกรมขนาดเล็กที่นับคะแนนของมือ Skat ดาดฟ้า Skat มีไพ่ 7 ถึง 10, Jack, Queen, King และ Ace (เรียกว่า Unter, Ober, Königและ Daus) เราใช้ชุดเยอรมันซึ่งมีต้นโอ๊กใบไม้ฮาร์ทส์และเบลล์แทน Clubs, Spades, Hearts และ Diamonds คะแนนจะถูกกำหนดโดยหมายเลขบนบัตร:

  • 7, 8 และ 9 คือ 0 คะแนน
  • Unter คือ 2 คะแนน
  • Ober คือ 3 คะแนน
  • โคนิกคือ 4 คะแนน
  • 10 คือ 10 คะแนน
  • Daus คือ 11 คะแนน

อินพุต / เอาต์พุต

รูปแบบการป้อนข้อมูลประกอบด้วยสองสัญลักษณ์โดยสัญลักษณ์แรกแสดงถึงค่าในขณะที่สัญลักษณ์ที่สองหมายถึงชุดสูท:

  • 7, 8 และ 9 ยืนหยัดเพื่อตนเอง
  • 0 (ศูนย์) หมายถึง 10
  • Unter, Ober, Königและ Daus ตั้งชื่อตามอักษรตัวแรกของพวกเขา (U, O และ D)
  • เช่นเดียวกันกับลูกโอ๊กใบไม้หัวใจและพุง (A, L, H และ B)

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

ตัวอย่าง

  • 7A 8A 9A UA OA KA 0A DA 7L 8L 9L UL OL KL 0L DL 7H 8H 9H UH OH KH 0H DH 7B 8B 9B UB OB KB 0B DBให้120
  • 7A 8L 0K DB 8L ให้ข้อผิดพลาด
  • UA OB DL KHให้20

กฎระเบียบ

  • รหัสกอล์ฟ: รหัสที่สั้นที่สุดชนะ
  • ใช้กฎการเล่นกอล์ฟแบบรหัสปกติ
  • โปรแกรมต้องทำงานให้กับทุกมือไม่ใช่แค่ตัวอย่างเท่านั้น
  • GIGO: หากอินพุตไม่ถูกต้องเอาต์พุตอาจถูกสุ่ม

เอาต์พุตเพิ่มเติมไปยัง stderr (เช่นคำเตือน) ใช้ได้หรือไม่
Ventero

@Ventero: ใช่มันเป็น วิธีที่จะผิดพลาดก็โอเค แต่ผู้ใช้จะต้องเห็นได้ชัดเจนว่ามีข้อผิดพลาด
FUZxxl

Jack, Queen และ Ace เรียกว่า Unter, Ober, Kingและ Daus? กษัตริย์ควรจะอยู่ที่นั่นไหม?
Ry-

@minitech ไม่มันไม่ใช่
FUZxxl

2
ฉันเชื่อว่าคุณหมายถึง "ระฆัง" ไม่ใช่ "ท้อง" แตกต่างกันมาก
บูธ

คำตอบ:


2

APL ( 54 48)

มีมีจะเป็นวิธีที่สั้นลงในการเลือกค่าบัตร แต่ผมไม่เห็นมัน

(+/12-'D0.....KOU.'⍳⊃¨A)÷A≡∪A←↓A⍴⍨2,⍨2÷⍨⍴A←⍞~' '

คุณจะได้รับDOMAIN ERRORถ้ามีการ์ดที่ซ้ำกัน

คำอธิบาย:

  • A←⍞~' ': store ( ) ลงในAบรรทัดอินพุตของผู้ใช้ ( ) โดยไม่มี ( ~) เว้นวรรค
  • 2,⍨2÷⍨⍴A: รายการสององค์ประกอบที่มีความยาวของ ( ) Aหารด้วย ( ÷⍨) 2 ตามด้วย ( ,⍨) หมายเลข 2 (ดังนั้นหากอินพุตคือUA OB DL KHรายการคือ (4, 2))
  • ↓A⍴⍨: กำหนดเมทริกซ์ ( ) ที่มีขนาดของรายการที่มีค่าเอจากนั้นเข้าร่วมองค์ประกอบของแถวของตนร่วมกัน ( ) ['UA','OB','DL','KH']ทำให้รายการของรายการตัวอย่างเช่น
  • A←: เก็บรายการนี้ใน A.
  • A≡∪A: ∪Aเป็นรายการองค์ประกอบที่ไม่ซ้ำกันใน A หากนี่เท่ากับ A จะไม่มีการซ้ำซ้อนและสิ่งนี้จะคืนค่า 1 มิฉะนั้นเป็น 0
  • ÷: แบ่งสิ่งที่อยู่ทางซ้าย (ซึ่งคำนวณตามจริง) โดยผลลัพธ์ของการทดสอบความเท่าเทียมกัน ดังนั้นหากไม่มีการซ้ำซ้อนคะแนนจะไม่เปลี่ยนแปลงและหากมีการซ้ำซ้อนคุณจะได้รับDOMAIN ERRORเนื่องจากการหารด้วยศูนย์
  • ⊃¨A: รายการที่ให้องค์ประกอบแรก ( ) ของแต่ละองค์ประกอบ ( ¨) ของ A ดังนั้นสิ่งนี้จะหยดตัวอักษรสูทโดยปล่อยให้จดหมายคะแนน ( UODK)
  • 'D0.....KOU.'⍳: ให้ดัชนีของตัวอักษรคะแนนแต่ละตัวในสตริงนี้ส่งคืน 12 สำหรับค่าที่ไม่ได้อยู่ในสตริง ( 10 9 1 8)
  • +/12-: ลบทั้งหมดเหล่านี้ออกจาก 12 แล้วเพิ่มเข้าด้วยกัน ( 2 + 3 + 11 + 4 = 20)


ฉันพลาดไปโดยสิ้นเชิงว่าคำตอบของคุณสั้นที่สุด
FUZxxl

10

Ruby 1.9, 52 ตัวอักษร

อินพุตผ่านอาร์กิวเมนต์บรรทัดรับคำสั่ง ฉันสมมติว่าข้อความแสดงข้อผิดพลาดเมื่อมีการ์ดที่ซ้ำกันไม่สำคัญดังนั้นเพียงแค่บ่นเกี่ยวกับข้อผิดพลาดการแปลงประเภท / eval

p eval$*.uniq!||$*.map{|i|"..UOK#$<.0D"=~/#{i}?/}*?+

ตัวอย่างการใช้งาน:

$ ruby1.9 skatscore.rb 7A 8A 9A UA OA KA 0A DA 7L 8L 9L UL OL KL 0L DL 7H 8H 9H UH OH KH 0H DH 7B 8B 9B UB OB KB 0B DB
120

$ ruby1.9 skatscore.rb 7A 7A
skatscore.rb:1:in `eval': can't convert Array into String (TypeError)
    from skatscore.rb:1:in `<main>'

ในมือข้างหนึ่งฉันคิดว่าข้อผิดพลาดของตัวแปรที่ไม่ได้กำหนดสำหรับการ์ดที่ซ้ำกันนั้นค่อนข้างอ่อนแอ ในทางกลับกันมันไม่ได้ผิดกฎดังนั้นมันจึงเป็นเรื่องที่ฉลาด
Igby Largeman

1
@Charles: เนื่องจากข้อมูลจำเพาะเพียงเรียกร้องให้ข้อผิดพลาดผมคิดว่าสิ่งที่ผิดพลาดตรงที่ไม่เกี่ยวข้องสวยมาก และหากมีวิธีการสั้น ๆ ในการผลิตข้อผิดพลาดใด ๆ ที่ควรจะดีฉันเดา
Joey


4

Haskell, 122 108 107 ตัวละคร

import List
main=interact$f.words
f x|nub x==x=show$sum$map(maybe 0 id.(`elemIndex`"  UOK     0D").head)x

error""undefinedจะสั้นกว่า interactบันทึกหนึ่งถ่านใช้
FUZxxl

@FUZxxl: การใช้interactมันจะไม่พิมพ์บรรทัดใหม่ดังนั้นฉันไม่แน่ใจว่าเป็นที่ยอมรับได้หรือไม่ undefinedแต่ผมก็สามารถที่จะประหยัดมากขึ้นโดยใช้รูปแบบที่ไม่สมบูรณ์แทน
hammar

ฉันพูดที่ไหนต้องขึ้นบรรทัดใหม่ ฉันจำไม่ได้
FUZxxl

2

GolfScript 54 53 52

แก้ไข 1:

ฉันเพิ่งค้นพบข้อผิดพลาดในรหัส มันไม่ได้ตรวจจับการ์ดที่ซ้ำกันหากมีการทำซ้ำสองครั้งแรกในอินพุต (เพราะฉันใช้ตัว*ดำเนินการแบบพับและไม่ใช่ตัว/ดำเนินการแต่ละตัวสำหรับลูปแรก)

ตอนนี้ฉันแก้ไขรหัสและจัดการเพื่อแยก 1 อักขระในกระบวนการ นี่คือเวอร์ชั่นใหม่:

' '/{1$1$?){]?}{\+}if}/2%{"UOK0D"\?).0>+.4>5*+}%{+}*

การป้อนข้อมูลที่จะต้องมีในสแต็คเป็นสตริงในรูปแบบที่กำหนด (ตัวอย่าง: '7A UA DA')

ในกรณีที่อินพุตถูกต้องโปรแกรมจะพิมพ์มูลค่ารวมของการ์ด

ในกรณีที่มีการ์ดที่ซ้ำกันอย่างน้อยหนึ่งการ์ดโปรแกรมจะแสดงข้อยกเว้นต่อไปนี้:

(eval):1:in `block in initialize': undefined method `class_id' for nil:NilClass (NoMethodError)

แก้ไข 2:

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

# Initially, we epect the input string to be on the stack
# Example: "7A UA DA"

' '/            # split the input string by spaces
                # now we have on the stack an array of strings
                # (in our example: ["7A" "UA" "DA"])

# {1$1$?)!{\+}{]?}if}/  -> this piece of code checks for duplicate cards
#
# The trailing symbol (/) is the 'each' operator, meaning that the 
# preceding code block (enclosed in curly brackets) will be executed 
# for every cards in the previous array.
#
# Before each execution of the code block, the current card value
# is pushed on the stack.
#
# Basically what this code does is concatenate cards into a string
# and checks whether the current card is contained in the accumulated
# value.
#
# So, for each card, this is what we execute:

1$              # copies the concatenated string on top of the stack
                # (initially this is an empty string)

1$              # copies the current card on top of the stack

?               # returns (places on the stack) the 0-based index where 
                # the current card is found in the concatenated string
                # or -1 if not found

)               # increments the topmost stack value
                # Now we have 0 if the card is not a duplicate
                # or a value greater than 0 otherwise

{]?}{\+}if      # if the current stack value is non-0 (duplicate)
                # then execute the first code {]?} (generates an error)
                # Otherwise, if the card is valid, execute the {\+} block.
                # What this code does is essentially concatenate the current 
                # card value:
                #    \ -> swaps the two topmost stack values; now we have
                #         the concatenated string and the current card value
                #    + -> this is the concatenation operator

# After the previous code block finishes execution (in case the input is)
# valid, we end up having the concatenated card values on the stack
# In our example, this value is "DAUAUB7A".

# The next code fragment is the one that computes the card values
# This is the code: 2%{"UOK0D"\?).0>+.4>5*+}%{+}*

# And this is how it can be broken down:

2%              # takes only the even indexed chars from the existing string 
                # in our case, "DAUA7A" -> "DU7"
                # Only these characters are important for determining the 
                # card values.

# The following piece of code is:
# {"UOK0D"\?).0>+.4>5*+}%

# This code performs a map; it takes the individual chars,
# computes the corresponding numeric value for each of them and outputs an
# array containing those values

# This is achieved using the map operator (%) which evaluates the preceding 
# code block, delimited by curly braces, so, essentially this is the code that 
# computes the value for a card:
# "UOK0D"\?).0>+.4>5*+
# It can be broken down like this:

"UOK0D"         # pushes the "UOK0D" string on the stack
\               # swaps the two topmost stack values
                # Now, these values are: "UOK0D" and "l" 
                # (where "l" represents the current letter
                # that gives the card its value: U,O,K,0,D,7,8...)

?               # Find the index of the card's letter in the
                # "UOK0D" string.
                # Remember, this is 0-based index, or -1 if not found.

)               # increment the index value
                # Now we have the following value:
                #     1 if the card is U
                #     2 if the card is O
                #     3 if the card is K
                #     4 if the card is 0
                #     5 if the card is D
                #     0 if it is anything else

.0>+            # if the current value is greater than 0,
                # add 1 to it.

.4>5*+          # if the current value is greater than 4,
                # add 5 to it.

# Passing through these steps, we now have the following value:
#     2  if the card is U
#     3  if the card is O
#     4  if the card is K
#     10 if the card is 0
#     11 if the card is D
#     0  if it is anything else
# This is the exact value we were looking for.

# Now we have an array containing the value of each card.
# in our example, [0, 2, 11]
# The next piece of code is easy:

{+}*            # uses the * (fold) operator to add up all the
                # values in the array.

# This leaves the total value of the cards on the stack,
# which is exactly what we were looking for (0+2+11=13).

# Golfscript is awesome! :-)

1

Python, 114 อักขระ

i=input().split();print(sum(int(dict(zip('7890UOKD','000A234B'))[x[0]],16)for x in i)if len(i)<=len(set(i))else'')

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


1

eTeX, 201 ตัวอักษร (ไม่นับการกระจายบรรทัดที่ไม่เกี่ยวข้องสองรายการ)

\def~#1#2{\catcode`#113\lccode`~`#1\lowercase{\def~}##1 {\ifcsname
#1##1 ~\D\fi\if\csname#1##1 ~\fi+"#2}}~70~80~90~0A~U2~O3~K4~DB\def
\a[#1]{\let~\endcsname\write6{^^J \the\numexpr#1 }\end}\expandafter\a

etex filename.tex [UA OB DL KH]ใช้เป็น การใส่อาร์กิวเมนต์ในวงเล็บปีกกาเป็นสิ่งจำเป็น: ไม่เช่นนั้น eTeX จะไม่มีวิธีพิจารณาว่าเรามาถึงจุดสิ้นสุดของรายการอาร์กิวเมนต์แล้ว

แก้ไข: ตามที่ได้รับอนุญาตในคำสั่งของคำถามการป้อนข้อมูลที่ไม่ถูกต้องอาจทำให้เกิดข้อผิดพลาด () ตัวอย่างเช่นetex filename.tex [OK]ขัดข้องอย่างน่ากลัว (เพราะKไม่ใช่สีที่ถูกต้อง)


ไม่ทำงานบนเครื่องของฉัน
FUZxxl

@FUZxxl อะไรคือผลลัพธ์ของetex -v? ข้อความแสดงข้อผิดพลาด (โดยประมาณ) คืออะไร รหัสควรจะใส่ในไฟล์ (ที่มีชื่อfilename.texหรือสิ่งอื่นที่ลงท้ายด้วย.tex) etex filename.tex [<argument>]และใช้ชื่อนั้นในบรรทัดคำสั่ง (ขออภัยที่จะโพสต์ความคิดเห็นเดิมอีกครั้งฉันลืม " @FUZxxl")
บรูโน่เลอฟลอช

โปรดดูที่นี่: hpaste.org/48949
FUZxxl

@FUZxxl ขอบคุณสำหรับความคิดเห็นของคุณ. Kไม่ใช่สีที่ถูกต้องและการแทนที่ด้วยXในตัวอย่างของคุณจะลบข้อผิดพลาด (มันล้มเหลวKเนื่องจากตัวอักษรนั้นมีความหมายอื่นนั่นคือราชา) ฉันสามารถทำให้ข้อผิดพลาดน้อยลงอย่างน่ากลัวโดยการเพิ่ม\stringก่อนหน้า##1แต่นั่นจะมีราคาเพิ่มขึ้น 12 ตัวอักษร
Bruno Le Floch

ขอโทษ ฉันทำผิดตัวอย่าง มันใช้งานได้แล้ว ขอโทษ
FUZxxl

1

PowerShell, 79 80

($a=$args|sort)|%{$s+=(10,11+4..0)['0DKOU'.IndexOf($_[0])]}
$s/("$a"-eq($a|gu))

การโยน»พยายามที่จะหารด้วยศูนย์«ถ้าไพ่ปรากฏสองครั้ง

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