Có bao nhiêu chuỗi Blackjack trong danh sách đó?


21

Nhiệm vụ của bạn là tìm kiếm có bao nhiêu chuỗi Blackjack riêng biệt có thể được tìm thấy trong một danh sách được sắp xếp gồm 12 thẻ.

Chuỗi Blackjack được định nghĩa là một chuỗi các thẻ liên tiếp có tổng số điểm chính xác là 21. Điểm được tính theo bảng sau:

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

Đầu vào

Chuỗi 12 ký tự, sử dụng các ký hiệu được mô tả ở trên. Chúng tôi không quan tâm đến màu sắc của thẻ, vì vậy chúng không được cung cấp.

Thí dụ:

K6K6JA3Q4389

Đầu ra

Số lượng các chuỗi Blackjack riêng biệt có thể được tìm thấy trong chuỗi đầu vào.

Thí dụ:

K6K6JA3Q4389 bao gồm hai chuỗi Blackjack riêng biệt:

thí dụ

  • JA, với Ace được tính là 11 điểm (10 + 11 = 21)
  • A3Q43, với Ace được tính là 1 điểm (1 + 3 + 10 + 4 + 3 = 21)

Vì vậy, câu trả lời sẽ là 2.

Quy tắc

  • Hai chuỗi Blackjack được coi là khác biệt nếu chúng chứa các thẻ khác nhau hoặc cùng một thẻ theo các thứ tự khác nhau. Nếu trình tự chính xác xuất hiện ở các vị trí khác nhau trong danh sách đầu vào, thì nó chỉ được tính một lần.
  • Các chuỗi Blackjack có thể chồng chéo lẫn nhau.
  • Mỗi loại thẻ có thể xuất hiện tối đa 12 lần trong chuỗi. (Chúng tôi giả định rằng các thẻ được chọn từ ít nhất 3 bộ bài khác nhau.)
  • Nếu không tìm thấy chuỗi Blackjack trong chuỗi đầu vào, bạn phải trả về 0hoặc bất kỳ giá trị giả nào khác.
  • Đây là môn đánh gôn, vì vậy câu trả lời ngắn nhất bằng byte sẽ thắng. Sơ hở tiêu chuẩn bị cấm.

Các trường hợp thử nghiệm

Các trình tự được cung cấp cho mục đích thông tin, nhưng bạn chỉ được yêu cầu xuất số lượng của chúng.

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, không nên giới hạn các chuỗi có độ dài từ 5 trở xuống?
Jonathan Allan

@Jonathan ALLan Đó là một điểm tốt. Tôi nghĩ đó thực sự là giới hạn trong một sòng bạc. Nhưng đây không phải là trò chơi Blackjack thực sự. Thay vào đó, tôi đã chọn giới hạn đầu vào ở mức 12 thẻ để nhiều Ách không yêu cầu quá nhiều thời gian tính toán. Nghe có ổn không?
Arnauld

Thử thách tiếp theo: Tìm chuỗi 12 char với chuỗi Blackjack độc đáo nhất: D
ETHproductions 15/2/2017

Việc giới hạn đầu vào xuống 10 thẻ sẽ dễ dàng hơn rất nhiều ...
Neil

@Neil Chà, điều đó sẽ làm cho trường hợp 'mười một Ách' không thể, nhưng có thực sự có một sự tối ưu hóa đáng kể đằng sau đó không? Tôi cho rằng bạn có thể có một cái gì đó khác trong tâm trí.
Arnauld

Câu trả lời:


6

Thạch , 30 29 byte

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

Dùng thử trực tuyến! hoặc kiểm tra bộ thử nghiệm

Làm sao?

Lưu ý rằng, nếu chúng ta luôn coi giá trị của ace là 1 thì tổng hợp lệ duy nhất là 2111 , thì sau này có thể chấp nhận được nếu ace xuất hiện trong chuỗi.

ẆÇÐ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 byte

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)

Bình luận thêm:

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 byte

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]):])})

Hãy thử trực tuyến!

Làm sao?

Một hàm không tên, lấy chuỗi có độ dài 12 là x.

x[i:j]là một lát chuỗi từ i + 1 ngày đến j thứ vật.

Lát được lấy ví dụ mà chúng tôi có tất cả các danh sách con bằng cách đi qua từ i=0đến i=11với for i in range(12), cho mỗi trong số đó chúng tôi đi qua từ j=0đến j=12với for j in range(13).

(Chúng tôi chỉ cần j=i+1và lên, nhưng các lát j<=ichỉ là các chuỗi trống, vì vậy chúng tôi có thể bỏ qua 4 byte từ for j in range(i+1,13))

Chúng được lọc cho những người có tổng ...

Các khoản tiền hợp lệ là 11 và 21 nếu có ace trong một lát, hoặc chỉ 21 nếu không. 'A'in x[i:j]cung cấp cho chúng tôi thông tin này và ~(v)thực hiện -1-v, mà chúng tôi sử dụng để cắt [11,21]- do đó, nếu ace nằm trong chuỗi chúng tôi nhận được [11,21][-2:]và nếu không chúng tôi nhận được [11,21][-1:], kết quả là [11,21][21]tương ứng.

Tổng bản thân cần phải điều trị Anhư 1, chữ số như giá trị của họ, và T, J, Q, và Knhư 10 bản đồ này được thực hiện bằng phương pháp đúc đầu tiên ordinals:
" 2 3 4 5 6 7 8 9 T J Q K A"(không có khoảng trắng) trở nên
[50, 51, 52, 53, 54, 55, 56, 57, 84, 74, 81, 75, 65], trừ 48 để có được
[ 2, 3, 4, 5, 6, 7, 8, 9, 36, 26, 33, 27, 17], lấy minvới 26 sản lượng
[ 2, 3, 4, 5, 6, 7, 8, 9, 26, 26, 26, 26, 17], và mod ( %) mười sáu trong số đó
[ 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10, 1], theo yêu cầu cho tổng , sum(...).

Các kết quả được lọc được đặt vào một tập hợp {...}, do đó, chỉ các kết quả duy nhất còn lại và độ dài, len(...)là số lượng


3

05AB1E , 39 38 37 byte

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

Hãy thử trực tuyến!

Giải trình

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

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>


Ý tưởng tuyệt vời, nhưng điều này trở lại 0cho AAAAAAAAAAAAhơn là 1. ( Acó thể đồng thời là 1 và 11)
Sản phẩm ETH

Bằng cách kết hợp hai mục nhập của chúng tôi, bạn có thể nhận được 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 byte
Sản phẩm ETH

@ETHproductions Bắt đầu từ 21 dường như vẫn tiết kiệm cho tôi một byte.
Neil

@ETHproductions ... thật hữu ích nếu tôi đăng số byte chính xác ...
Neil

3

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

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

Nỗ lực cũ ở 128:

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`>-1có thể là~s.search`A`
Luke

@Luke Không, thực sự, bởi vì điều đó trả về các giá trị như -2, và1&-2 == 0
Sản phẩm ETH

Thật. Có thể được đặt tthành 0trong .slice(0,-1)cuộc gọi (tiết kiệm 2B)?
Lu-ca

@Luke Tôi không nghĩ rằng nó sẽ hoạt động, như tlà một biến toàn cục và nó sẽ được đặt lại vì cuộc gọi đến f(s.slice(0,-1)). Nhưng tôi đã tìm thấy một cách xung quanh s.search`A`>-1:-)
Sản phẩm điện tử

Tôi tò mò muốn xem những gì bạn có khi bạn chơi golf này. Tôi dường như bị mắc kẹt ở 113 bây giờ.
Arnauld

3

JavaScript (ES6), 112 byte

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

Logic mã này khá giống với logic được sử dụng trong các câu trả lời JS hiện có từ ETHproductionsNeil . Nhưng đó là sử dụng một mảng cơ bản để theo dõi các chuỗi Blackjack gặp phải thay vì a Set.

Định dạng và nhận xét

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

Các trường hợp thử nghiệm


Tôi đã thử đệ quy gấp đôi, di chuyển ngược qua chuỗi, tính toán tích lũy từng chuỗi có thể khi mỗi ký tự được tiêu thụ ... và cách tiếp cận ngắn nhất chỉ đơn giản là chạy qua từng lát. Đẹp quá (Sử dụng Tập có vẻ dài hơn ba byte, nếu tôi tính toán chính xác)
ETHproductions 17/2/2017

2

05AB1E , 40 39 38 37 36 byte

-4 Cảm ơn Emigna

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

Hãy thử trực tuyến!

Ç<ç                                  # 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

Chúng ta cần thực hiện giảm dần -> chuỗi con -> điều tăng để thẻ mặt được biểu thị bằng một số có một chữ số.


Cách tốt đẹp để có được khoảng hai chữ số! Bạn có thể xóa cái đầu tiên Skhi Çbiến chuỗi thành một danh sách mã ký tự.
Emigna

Ngoài ra, "SIPJ"có thể là„èµJu
Emigna

@Emigna Cảm ơn. Tôi nghĩ rằng có một cách để làm điều đó, nhưng tôi không thể tìm thấy cách sử dụng trong tài liệu.
Riley

Bạn có thể lưu thêm 2 byte để viết lại khi Ç<çJŒÙ'@0:)vy„èµJuS9:S>D1å2‚T*>sOå}Ođó là 1 byte ngắn hơn câu trả lời của tôi :)
Emigna

@Emigna Đây là số byte tương tự và giống với bản gốc của tôi hơn.
Riley

1

Tiện ích Bash + Unix, 145 142 141 byte

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

Hãy thử trực tuyến!

Chạy thử:

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 byte

$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));

Ung dung:

$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));

Hãy thử nó ở đây!


1
Thật kỳ lạ, tôi có thể đã thề rằng nó đã làm việc trong các bài kiểm tra địa phương của tôi, nhưng có vẻ như bạn đúng. Dù sao; vấn đề xuất phát từ thực tế $ikhông được tuyên bố. Đã thêm 4 byte và nó hoạt động hoàn hảo.
roberto06
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.