Skat için sayı sayacı


11

Göreviniz bir Skat elinin puanlarını sayan küçük bir program yazmak. Skat destesinde 7-10 arası kartlar, Jack, Kraliçe, Kral ve As (Unter, Ober, König ve Daus olarak adlandırılır) bulunur. Kulüpler, Maçalar, Kalpler ve Elmaslar yerine Meşe Palamudu, Yapraklar, Kalpler ve Çanları olan Alman takımlarını kullanıyoruz. Puanlar karttaki numaraya göre belirlenir:

  • 7, 8 ve 9 0 puan
  • Unter 2 puan
  • Ober 3 puan
  • König 4 puan
  • 10 10 puan
  • Daus 11 puan.

Giriş çıkış

Giriş biçimi iki simgeden oluşur, ilki değeri temsil ederken, ikincisi takım elbisesini temsil eder:

  • 7, 8 ve 9 kendileri için duruyor
  • 0 (sıfır) 10 anlamına gelir
  • Unter, Ober, König ve Daus ilk harflerinden (U, O ve D) sonra adlandırılır
  • Aynı meşe palamudu, yaprak, kalp ve göbek (A, L, H ve B)

Giriş, tek bir boşlukla ayrılmış tek bir kart dizisidir. Girdiyi istediğiniz yerden alabilirsiniz, komut satırı bağımsız değişkenleri de uygundur. Çıktı, yazdırılan veya çıkış kodu olarak döndürülen elin değeridir. Elinizde iki kart varsa, programınızın çıktısında bir hata gösterilmelidir. (Bunun 7A 0L 7Ayerine bir hata döndürmelidir 10). Programın sonucun çıktısını almak için varsayılan yolu bu ise, hata göstermek yerine 255 çıkış koduyla çıkmak da uygundur.

Örnekler

  • 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 DB120 verir
  • 7A 8L 0K DB 8L hata veriyor
  • UA OB DL KH20 verir

kurallar

  • Code golf: En kısa kod kazanır
  • Normal kod golf kuralları geçerlidir
  • Program sadece örnekler için değil, tüm eller için çalışmalıdır.
  • GIGO: Giriş geçersizse, çıktı keyfi olabilir

Stderr'e ek çıktı (örn. Uyarılar) iyi mi?
Ventero

@Ventero: Evet, öyle. Hata yapmanın herhangi bir yolu iyidir, ancak kullanıcı tarafından bir hata olduğu açıkça görülebilir olmalıdır.
FUZxxl

Jack, Queen ve Ace'e Unter, Ober, King ve Daus denir ? Bir kral orada mı olmalı?
Ry-

@minitech Hayır, değil.
FUZxxl

2
İnanıyorum ki "göbek" değil, "çanlar". Çok farklı, bu.
boothby

Yanıtlar:


2

APL ( 54 48)

Orada vardır kart değerini seçerek daha kısa bir yol olarak, ama onu göremiyorum.

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

DOMAIN ERRORYinelenen bir kart varsa alırsınız .

Açıklama:

  • A←⍞~' ': ( ) boşlukları olmayan bir kullanıcı girişi ( ) satırına ( ) depolar .A~
  • 2,⍨2÷⍨⍴A: uzunluğunun ( ) Abölünmesiyle ( ÷⍨) 2 ve ardından ( ) 2 ,⍨sayısını içeren iki elemanlı bir liste . (Yani, giriş UA OB DL KHliste ise (4, 2)).
  • ↓A⍴⍨: listenin boyutları ile A değerlerini içeren bir matris ( ) tanımlayın . Ardından , örneğin bir liste listesi vererek satırlarının öğelerini birleştirin ( ) ['UA','OB','DL','KH'].
  • A←: Bu listeyi A'da saklayın.
  • A≡∪A: ∪AA'daki benzersiz öğelerin listesidir. Bu A'ya eşitse, yineleme yoktur ve bu 1 değerini döndürür, aksi takdirde 0 değerini döndürür.
  • ÷: eşitlik testinin sonucuna solda bulunanı (gerçek hesaplamayı yapar) böl. Dolayısıyla, kopya yoksa, puan değişmez ve kopyalar varsa DOMAIN ERROR, sıfıra bölünme nedeniyle alırsınız .
  • ⊃¨A: A'nın her bir öğesinin ( ¨) ilk elemanını ( ) veren bir liste, bu da takım harfini düşürerek puan mektubunu bırakır. ( UODK)
  • 'D0.....KOU.'⍳: bu dizgideki her bir skor harfinin dizinini verir, dizede olmayan değerler için 12 değerini döndürür. ( 10 9 1 8)
  • +/12-: Bunların hepsini 12'den çıkarın ve ardından toplayın. ( 2 + 3 + 11 + 4 = 20)


Cevabınızın en kısa olduğunu tamamen özledim.
FUZxxl

10

Yakut 1.9, 52 karakter

Komut satırı bağımsız değişkenleri aracılığıyla giriş yapın. Yinelenen kartlara sahip olmak hata mesajı varsayarım, bu yüzden sadece bir eval / tip dönüşüm hatası hakkında şikayet ediyor.

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

Örnek kullanım:

$ 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>'

Bir yandan, yinelenen kartlar için tanımlanmamış değişken hatası biraz topal olduğunu düşünüyorum. Öte yandan, kuralları çiğnemez, bu yüzden biraz zekidir.
Igby Largeman

1
@Charles: Spesifikasyon sadece bir hata istediğinden, hangi hatanın hemen hemen ilgisiz olduğunu tahmin ediyorum . Ve eğer herhangi bir hata üretmenin kısa yöntemleri varsa, bu iyi olmalı, sanırım.
Joey

6

Scala, 87 82 karakter

args.distinct(args.size-1);println(args.map(a=>1+" UOK     0D".indexOf(a(0))).sum)

Tekrarlanan kartlara bir istisna atar.


4

Haskell, 122 108 107 karakter

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

error""daha kısadır undefined. Düğmesini kullanarak bir karakter kaydedin interact.
FUZxxl

@FUZxxl: interactBunu kullanmak yeni bir satır yazdırmayacak, bu yüzden bunun kabul edilebilir olup olmadığından emin değilim. Ancak, yerine eksik bir desen kullanarak çok daha fazla tasarruf sağlayabildim undefined.
Hamar

Nereden bir satırsonuna ihtiyaç olduğunu söyledim? Hatırlayamıyorum.
FUZxxl

2

GolfScript 54 53 52

Düzenleme 1:

Kodda bir hata buldum. Kopyalar girişte ilk iki ise çift kartları tespit etmedi (çünkü ilk döngü için her operatörü *değil, katlama operatörünü kullanıyordum /).

Şimdi kodu sabitledim ve aynı zamanda süreçte 1 karakter çıkarmayı başardım. İşte yeni sürüm:

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

Girdinin, belirtilen biçimde yığında bir dize olarak olması gerekir (örnek:) '7A UA DA'.

Girişin geçerli olması durumunda, program kartların toplam değerini yazdırır.

En az bir çift kart olması durumunda, program aşağıdaki istisnayı atar:

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

Düzenleme 2:

Meta sitede bu yayını gördükten sonra , kodun bir açıklamasını göndermeye karar verdim. Bu da bir hatayı bulmamı ve düzeltmemi sağladı. Yani, işte gidiyor:

# 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 karakter

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

Ne yazık ki, indexPython'daki listeler yöntemi, negatif bir değer döndürmek yerine bir öğe bulunmazsa ve içe aktarma kaydedilenden defaultdictdaha fazla karakter gerektiriyorsa bir hata oluşturur .


1

eTeX, 201 karakter (iki alakasız çizgi işaretini saymaz)

\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

Olarak kullanılır etex filename.tex [UA OB DL KH]. Argümanı parantez içine almak zorunludur: aksi takdirde eTeX'in argüman listesinin sonuna geldiğimizi belirleme yolu yoktur.

EDIT: sorunun ifadesinde izin verildiği gibi yanlış giriş (an) hatasına neden olabilir. Örneğin, etex filename.tex [OK]korkunç bir şekilde çöküyor (çünkü Kgeçerli bir renk değil).


Makinemde çalışmıyor.
FUZxxl

@FUZxxl. Çıktısı nedir etex -v? Hata mesajı nedir (kabaca)? Kod bir dosyaya (adla filename.texveya biten başka bir şeyle .tex) konulmalı ve komut satırında bu ad kullanılmalıdır etex filename.tex [<argument>]. (aynı yorumu yayınladığım için üzgünüm, " @FUZxxl" unuttum )
Bruno Le Floch

Lütfen buraya bakın: hpaste.org/48949
FUZxxl

@FUZxxl. Geri bildiriminiz için teşekkür ederiz. Kgeçerli bir renk değildir ve Xörneklerinizle değiştirilmesi , hataları kaldırır (bu Kharfin başka bir anlamı olduğu için çöküyor , King). \stringHer birinden önce ekleyerek hatayı daha az korkunç hale getirebilirdim ##1, ancak bu 12 karakter daha mal olacak.
Bruno Le Floch

Afedersiniz. Örneği yanlış yazdım. Şu an çalışıyor. Afedersiniz.
FUZxxl

1

PowerShell, 79 80

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

Atar »Kartlar iki kez görünürse, sıfıra bölmeye çalışır.«

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.