Bu listede kaç tane Blackjack dizisi var?


21

Göreviniz, 12 kartlık bir sıralı listede kaç tane farklı Blackjack dizisi bulunabileceğini bulmak.

Bir Blackjack dizisi, toplam puanları tam olarak 21 olan ardışık kart dizisi olarak tanımlanır. Aşağıdaki tabloya göre puanlar sayılır:

Symbol | Name  | Points     Symbol | Name  | Points
-------+-------+--------    -------+-------+--------
   2   | Two   | 2             9   | Nine  | 9
   3   | Three | 3             T   | Ten   | 10
   4   | Four  | 4             J   | Jack  | 10
   5   | Five  | 5             Q   | Queen | 10
   6   | Six   | 6             K   | King  | 10
   7   | Seven | 7             A   | Ace   | 1 or 11
   8   | Eight | 8

Giriş

Yukarıda açıklanan sembolleri kullanarak 12 karakterli bir dize. Kartların renklerini umursamıyoruz, bu yüzden sunulmuyor.

Örnek:

K6K6JA3Q4389

Çıktı

Giriş dizesinde bulunabilecek farklı Blackjack dizilerinin sayısı.

Örnek:

K6K6JA3Q4389 iki farklı Blackjack dizisi içerir:

örnek

  • JAAs, 11 puan olarak sayılır (10 + 11 = 21).
  • A3Q43, As 1 puan olarak sayılır (1 + 3 + 10 + 4 + 3 = 21)

Yani cevap olurdu 2.

kurallar

  • İki Blackjack dizisi, farklı kartlar veya aynı kartlar farklı sıralar içerdiğinde farklı olarak kabul edilir. Tam olarak aynı sıralama giriş listesindeki farklı konumlarda görünüyorsa, sadece bir kez sayılmalıdır.
  • Blackjack dizileri birbiriyle örtüşebilir.
  • Her tür kart, dizide en çok 12 kez görünebilir. (Kartların en az 3 farklı desenden alındığını varsayıyoruz.)
  • Giriş dizisinde Blackjack dizisi bulunamazsa, geri 0dönmelisiniz veya başka bir sahte değer.
  • Bu kod golf, yani bayt cinsinden en kısa cevap kazanır. Standart boşluklar yasaktır.

Test durumları

Diziler bilgi amaçlı verilmiştir, ancak yalnızca sayılarını vermeniz gerekir.

Input        | Output | Distinct sequences
-------------+--------+--------------------------------------------------------
3282486Q3362 | 0      | (none)
58A24JJ6TK67 | 1      | 8A2
Q745Q745Q745 | 1      | Q74
AAAAAAAAAAAA | 1      | AAAAAAAAAAA
T5AQ26T39QK6 | 2      | AQ, 26T3
JQ4A4427464K | 3      | A442, 44274, 7464
Q74Q74Q74Q74 | 3      | Q74, 74Q, 4Q7
37AQKA3A4758 | 7      | 37A, 37AQ, AQ, AQK, QKA, KA, A3A475
TAQA2JA7AJQA | 10     | TA, TAQ, AQ, QA, A2JA7, 2JA7A, JA, AJ, AJQ, JQA
TAJAQAKAT777 | 13     | TA, TAJ, AJ, JA, JAQ, AQ, QA, QAK, AK, KA, KAT, AT, 777

1
Hmm, diziler 5 ya da daha az uzunluklarla sınırlandırılmamalı mı?
Jonathan Allan,

@ JonathanAllan Bu iyi bir nokta. Bunun gerçekten bir kumarhanede limiti olacağını düşünüyorum. Ama bu gerçek bir Blackjack oyunu değil. Bunun yerine, girişi 12 karta sınırlamayı seçtim, böylece birçok As çok fazla hesaplama süresi gerektirmiyor. Bu iyi mi?
Arnauld,

Sıradaki zorluk: En eşsiz Blackjack dizileriyle 12 karakterli dizgiyi bulun: D
ETHproductions

Girişi 10 karta sınırlamak çok daha kolay olurdu ...
Neil

@Neil, bu 'on As' davasını imkansız hale getirecekti, ama bunun arkasında gerçekten önemli bir optimizasyon var mı? Sanırım aklında başka bir şey olabilir.
Arnauld,

Yanıtlar:


6

Jöle , 30 29 bayt

1e×5,⁵Ḥ‘
O_48«26%⁴µSeÇ
ẆÇÐfQL

Çevrimiçi Deneyin! veya test odasına göz atın

Nasıl?

Bir ası her zaman 1 olarak değerlendiriyorsak , sadece geçerli toplamlar 21 ve 11'dir , ikincisi, bir as sekansta görünürse kabul edilebilir olur.

ẆÇÐfQL - Main link: string
Ẇ      - all non-empty contiguous sublists
  Ðf   - filter keep if...
 Ç     -     last link (2) as a monad ...is truthy
    Q  - unique results
     L - length

O_48«26%⁴µSeÇ - Link 2, isBlackjackSubtring: char array  e.g. ['A','2','8','Q']
O             - cast to ordinal values                        [ 65, 50, 56, 81]
 _48          - subtract 48                                   [ 17,  2,  8, 33]
     26       - 26
    «         - minimum (vectorises)                          [ 17,  2,  8, 26]
        ⁴     - 16
       %      - modulo                                        [  1,  2,  8, 10]
         µ    - monadic chain separation (call the result v)
          S   - sum(v)                                        21
            Ç - last link (1) as a monad link_1(v)            [11,21]
           e  - exists in?                                    1

1e×5,⁵Ḥ‘ - Link 1 validSums: value list (where A is 1, and {T,J,Q,K} are 10)
1e       - 1 exists in? (are there any aces? Yields 1 or 0)
  ×5     - multiply by 5 (5 or 0)
     ⁵   - 10
    ,    - pair ([5,10] or [0,10])
      Ḥ  - double ([10,20] or [0,20])
       ‘ - increment ([11,21] or [1,21])
         -                        ^
         -     note: if no ace is in the sequence it's sum can't be 1 anyway

7

Python 2, 215 bayt

def b(s,a=[],r=range):
 S=map(lambda x:":">x>"1"and int(x)or 10-(x=="A")*9,s)
 for i in r(12):
  for j in r(13):
   if 21in[x*10+sum(S[i:j])for x in r(S[i:j].count(1)+1)]and s[i:j]not in a:a+=s[i:j],
 return len(a)

Yorumlar eklendi:

def b(s,a=[],r=range):                                      # Define the function b and a list, a, which holds all the blackjack sequences
 S=map(lambda x:":">x>"1"and int(x)or 10-(x=="A")*9,s)      # Set S to the score of each card in b
 for i in r(12):                                            # Loop with i from 0 to 11
  for j in r(13):                                           # Loop with j from 0 to 12
   if 21in[x*10+sum(S[i:j])for x in r(S[i:j].count(1)+1)]\  # If 21 is included in all the possible sums that the scores between i and j in S can be
           and s[i:j]not in a:                              # And that sequence is not already included,
               a+=s[i:j],                                   # Append that sequence to a
 return len(a)                                              # Return the amount of elements in a

3

Python , 134 130 bayt

lambda x:len({x[i:j]for i in range(12)for j in range(13)if sum(min(26,ord(c)-48)%16for c in x[i:j])in([11,21][~('A'in x[i:j]):])})

Çevrimiçi deneyin!

Nasıl?

Uzunluk dizgesini 12 olarak alan isimsiz bir fonksiyon x.

x[i:j]i + 1 den dize bir dilim th j için inci karakteri.

Dilimler biz gelen değiştirme tertibatı bütün sublists sahip olduğu şekilde alınır i=0için i=11olan for i in range(12)biz gelen çapraz olan her biri için, j=0karşı j=12ile for j in range(13).

(Sadece j=i+1yukarıya ve yukarıya ihtiyacımız var , ancak dilimler j<=isadece boş dizeler, bu nedenle 4 bayttan golf oynayabiliriz for j in range(i+1,13))

Bunlar doğru toplamı olanlara ...

Bir dilimde bir as varsa geçerli toplamlar 11 ve 21, değilse de 21'dir. 'A'in x[i:j]Bu bilgileri bize ve verir ~(v)gerçekleştirir -1-vbiz dilim kullanmak, [11,21]bir as aldığımız sırayla olduğunu böylece eğer - [11,21][-2:]ve biz alamadım eğer [11,21][-1:], neden [11,21]ve [21]sırasıyla.

Kendisi bir tedavi ihtiyacı toplamı A1 olarak, değerleri olarak parmaklara ve T, J, Qve K10 gibi bu eşleme sıra sayıları ilk döküm ile elde edilmektedir:
" 2 3 4 5 6 7 8 9 T J Q K A"(boşluksuz) olur
[50, 51, 52, 53, 54, 55, 56, 57, 84, 74, 81, 75, 65], elde etmek için 48 çıkarılarak
[ 2, 3, 4, 5, 6, 7, 8, 9, 36, 26, 33, 27, 17]alarak min26 verimi ile
[ 2, 3, 4, 5, 6, 7, 8, 9, 26, 26, 26, 26, 17], ve mod ( %) on altı
[ 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 1], toplam için gerekli olanlardır sum(...).

Filtrelenen sonuçlar bir kümeye yerleştirilir {...}, bu nedenle yalnızca benzersiz sonuçlar kalır ve uzunluk len(...)sayımdır.


3

05AB1E , 39 38 37 bayt

'A1:vTy‚ydè})ŒvyO¸y1åiDT+ì}21å})¹ŒÏÙg

Çevrimiçi deneyin!

açıklama

'A1:                  # replace A with 1 in input

v      }              # for each card
 Ty‚                  # pair 10 and the card
    yd                # check if the card is a digit
      è               # use this to index into the pair, giving 10 for JQK
        )             # wrap in list
                      # we now have a list of cards as numbers in range [1 ... 10]

Œv               }    # for each sublist
  yO¸                 # create a list with the sum of the sublist
     y1åi    }        # if the sublist contain 1
         DT+ì         # add sum+10 to the list
              21å     # check if 21 is in that list
                  )   # wrap in list
                      # we now have a list with 1 where the sublist sums to 21 and
                      # 0 otherwise

¹Œ                    # get sublists of the input
  Ï                   # keep only those which sum to 21
   Ù                  # remove duplicates
    g                 # count the number of lists

3

JavaScript (ES6), 123 bayt

f=
t=>eval("for(s=new Set,i=0;t[i];i++)for(a=0,b=21,j=i;c=t[j++];b&&b-a*10||s.add(t.slice(i,j)))b-=+c||(c>'A'?10:a=1);s.size")
<input oninput=o.textContent=/[^2-9TJQKA]/.test(this.value)?'':f(this.value)><pre id=o>


Büyük fikir, ama bu döner 0için AAAAAAAAAAAAyerine 1. ( Aaynı anda 1 ve 11 olabilir)
ETHproductions 21

İki girişi birleştirerek s=>eval("q=new Set;for(i=0;s[i];i++)for(t=A=0,j=i;c=s[j++];t==21|t==11&A&&q.add(s.slice(i,j)))t+=+c||(c<'B'?A=1:10);q.size")124 bayt alabilirsiniz
ETHproductions

@ETHproductions 21'den başlamak hala bir bayt kurtarıyor gibi görünüyor.
Neil,

@ETHproductions ... doğru byte sayısını gönderirsem yardımcı olur ...
Neil

3

JavaScript (ES6), 144 138 129 128 126 124 bayt

g=([c,...s],a=[],q=new Set)=>c?g(s,[...a,[,21]].map(([x,y,A])=>[x+=c,y-=+c||(c<'B'?A=1:10),A,y&&y^10*A||q.add(x)]),q):q.size

128'deki eski deneme:

s=>(q=new Set,f=s=>s?f(s.slice(1))&f(s.slice(0,-1))&[...s].map(c=>t+=-c||~(c<'B'?A=0:9),t=A=21)|t&&t-10*!A?q:q.add(s):q)(s).size

s.search`A`>-1olabilir~s.search`A`
Luke,

@Luke Hayır, aslında, çünkü -2, ve1&-2 == 0
ETHproductions

Doğru. Belki set tiçin 0de .slice(0,-1)çağrı (kaydeder 2B)?
Luke,

@Luke Bunun tglobal bir değişken olduğu gibi çalışacağını ve arama nedeniyle sıfırlanacağını sanmıyorum f(s.slice(0,-1)). Ancak s.search`A`>-1:-) etrafında bir yol buldum
ETHproductions

Bu golf oynamak bittiğinde ne olduğunu görmek merak ediyorum. Şimdilik 113'te sıkışmış gibiyim.
Arnauld,

3

JavaScript (ES6), 112 bayt

f=(s,x=[k=0])=>s?f(s.slice(1),x,[...s].map(c=>x[t+=+c||10^(c<'B'?a=11:0),b+=c]||t-21&&t-a?0:x[b]=++k,a=b=t=0)):k

Bu kod mantığı, ETHproductions ve Neil'in mevcut JS cevaplarında kullanılana oldukça benzer . Ancak, karşılaşılan Blackjack dizilerini takip etmek yerine basit bir dizi kullanıyor.Set .

Biçimlendi ve yorumlandı

f = (                     // given:
  s,                      //  - s = list of cards
  x = [k = 0]             //  - x = array of Blackjack sequences
) =>                      //  - k = number of distinct Blackjack sequences 
  s ?                     // if s is not empty:
    f(                    //   do a recursive call:
      s.slice(1),         //     starting at the next card in the list
      x,                  //     without re-initializing x[]
      [...s].map(         //   for each card 'c' in the list:
        c => x[           //
          t+ =            //   update the total number of points:
            +c ||         //     using the number of the card (for 2 ... 9)
            10 ^ (        //     or using 10 for all other cards
              c < 'B' ?   //     except the Ace which is
                a = 11    //     counted as 1 point and sets 'a' to 11
              :           //     (which means that a total number of points
                0         //     of 11 will be considered valid from now on)
            ),            //
          b += c          //   update the current sequence 'b'
        ] ||              //   if x[b] was previously stored as a Blackjack sequence
        t - 21 &&         //   or the total number of points is not equal to 21
        t - a ?           //   and not equal to 'a':
          0               //     do nothing
        :                 //   else:
          x[b] = ++k,     //     store the current sequence in x[] and increment k
        a = b = t = 0     //   initialization of all variables used in map()
      )                   //
    )                     //
  :                       // else:
    k                     //   return k

Test durumları


İkili özyinelemeyi denedim, ipte geriye doğru hareket ettim, her karakter tüketilirken mümkün olan her ipi kümülatif olarak hesapladım ... ama yine de en kısa yaklaşım her dilimden geçmek. Güzel bir! (Bir Küme kullanmak, doğru hesapladıysam üç bayt daha uzun görünür)
ETHproductions

2

05AB1E , 40 39 38 37 36 bayt

-4 Emigna'ya teşekkürler

Ç<çJŒÙ'@0:[Ž„èµJuS9:S>D1å2‚T*>sOå½]¾

Çevrimiçi deneyin!

Ç<ç                                  # decrement characters by 1
   JŒÙ                               # get all unique substrings
      '@0:                           # replace @ (was A) with 0
          [Ž                      ]  # for everything on the stack
            „èµJuS9:                 # replace what was T,J,Q,K with 9
                    S>D              # increment all values
                       1å2‚T*>       # push [11,21] if there was an A, [1,21] otherwise
                              sO     # sum the values of the cards
                                å½   # increment the counter_variable if the sum 
                                     # is in the array
                                   ¾ # end loop and push (print) the counter_variable

Yüz kartlarının tek basamaklı bir sayı ile gösterilmesi için -> substring -> artırma işleminin azaltılması gerekir.


Çift haneli dolaşmanın güzel bir yolu! İlk Solarak Çdizeyi karakter kodları listesine dönüştüren listeyi kaldırabilirsiniz .
Emigna

Ayrıca, "SIPJ"olabilir„èµJu
Emigna

@Emigna Teşekkürler. Bunu yapmanın bir yolu olduğunu düşündüm, ancak belgelerde nasıl kullanılacağını bulamadım .
Riley,

Yeniden yazarken 2 bayttan tasarruf edebilirsiniz. Ç<çJŒÙ'@0:)vy„èµJuS9:S>D1å2‚T*>sOå}OSonra
cevabımdan

@Emigna Bu, aynı byte sayımıdır ve daha çok orjinalim gibidir.
Riley,

1

Bash + Unix yardımcı programları, 145 142 141 bayt

for n in {9..155}
{ echo ${1:n%12:n/12};}|sort -u|sed 's/\(.\)/+\1/g;s/A/{1,11}/g;s/[J-T]/10/g;s/^/eval echo $[0/;s/$/]/'|sh|grep -c '\<21\>'

Çevrimiçi deneyin!

Test çalıştırması:

for x in 3282486Q3362 58A24JJ6TK67 Q745Q745Q745 AAAAAAAAAAAA T5AQ26T39QK6 JQ4A4427464K Q74Q74Q74Q74 37AQKA3A4758 TAQA2JA7AJQA TAJAQAKAT777
  do
    echo -n "$x "
    ./21 "$x"
  done

3282486Q3362 0
58A24JJ6TK67 1
Q745Q745Q745 1
AAAAAAAAAAAA 1
T5AQ26T39QK6 2
JQ4A4427464K 3
Q74Q74Q74Q74 3
37AQKA3A4758 7
TAQA2JA7AJQA 10
TAJAQAKAT777 13

1

PHP, 240 bayt

$a=str_split($argv[1]);foreach($a as$k=>$v)$n[$k]=$v=='A'?1:($v==0?10:$v);for($i=0;$i<=$k;$i++){$s=$a[$i];$r=$n[$i];for($j=$i+1;$j<=$k;$j++){$s.=$a[$j];$r+=$n[$j];if ($r==21||($r==11&&stristr($s,'A')))$f[]=$s;}}echo count(array_unique($f));

Ungolfed:

$a = str_split($argv[1]);
foreach ($a as $k=>$v)
    $n[$k] = $v == 'A' ? 1 : ($v == 0 ? 10 : $v);
for ($i=0; $i<=$k; $i++) {
    $s = $a[$i];
    $r = $n[$i];
    for ($j=$i+1; $j<=$k; $j++) {
        $s .= $a[$j];
        $r += $n[$j];
        if ($r == 21 || ($r == 11 && stristr($s,'A')) )
            $f[] = $s;
    }
}
echo count(array_unique($f));

Burada dene!


1
Garip, yerel sınavlarım üzerinde çalıştığına yemin edebilirdim, ama haklı görünüyorsunuz. Neyse; sorun $iilan edilmemiş olmasından kaynaklanıyordu . 4 bayt eklendi ve mükemmel çalışıyor.
roberto06
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.