Siapa yang memenangkan trik Sekop

19

Tulis kode untuk menentukan siapa yang memenangkan trik empat kartu dalam permainan Spades . Bytes paling sedikit menang.

Input adalah string yang berisi daftar empat kartu yang dimainkan secara berurutan seperti TH QC JH 2H(Sepuluh Hati, Ratu Klub, Jack Hati, Dua Hati). Kartu diberikan oleh dua karakter: setelan dari CDHSdan nilai dari 23456789TJQKA. Anda dijamin bahwa inputnya valid dan kartunya berbeda.

Anda harus menampilkan angka 1, 2, 3, atau 4 untuk pemenang trik. Dalam contoh TH QC JH 2H, jack of heart memenangkan trik, jadi Anda harus menampilkan 3.

Input dan output Anda harus persis seperti yang dijelaskan, kecuali mengikuti baris baru adalah opsional.

Berikut adalah aturan Sekop untuk memenangkan tipuan. Kartu yang menang adalah kartu tertinggi dari empat, dengan beberapa peringatan. Sekop adalah setelan truf , jadi setiap sekop mengalahkan yang bukan sekop. Suit kartu pertama yang dimainkan adalah suit utama , dan hanya kartu dari suit atau sekop yang memenuhi syarat untuk memenangkan trik. Kartu dengan jenis yang sama dibandingkan dengan nilainya, yang diberikan dalam urutan yang meningkat seperti 23456789TJQKA.

Kasus uji:

TH QC JH 2H
3
KC 5S QS 9C
3
QD 2D TD 5D
1
9S 5D AD QS
4
3D 4C 3H JH
1
9S 4S TS JS
4
5H 9H 2C AD
2
5S 4C 3H QD
1
2H 2S KH AH
2
Tidak
sumber

Jawaban:

10

Pyth, 28 27 25 byte

J"KTAZ"hxcz)eo_XN+@z1JJcz

Cobalah online: Demonstrasi atau Test Suite (4 karakter pertama adalah konstruk test suite)

Berkat @isaacg untuk sebuah trik, yang menyelamatkan 2 karakter.

Gagasan utamanya adalah memodifikasi karakter masing-masing tangan sedemikian rupa, sehingga kartu yang menang memiliki nilai maksimal.

Nilai tangan 23456789TJQKAsudah hampir diurutkan. Saya hanya harus mengganti Tdengan A, Kdengan Tdan Adengan Z, yang dihasilkan dengan 23456789AJQSZ.

Urutan pakaian CDHSuntuk yang paling tidak terlalu penting. S, setelan paling kuat, yang sudah menjadi nilai maksimal. Penting adalah untuk memberikan nilai pertama yang paling kuat pada gugatan tangan pertama. Jadi saya menerjemahkan gugatan ini menjadi K.

Semua tangan juga harus dibaca terbalik, karena setelan itu lebih kuat daripada nilainya.

                           implicit: z = input string
J"KTAZ"                    J = "KTAZ"
             o         cz  orders the hands N of split(z) by:
              _              the reversed of 
               XN+@z1JJ      N, where the values z[1]+J are replaced by J
            e              last element (winning hand)
        xcz)               index of the winning hand in split(z)
       h                   + 1
Jakube
sumber
Saya menyerah, bermain dengan baik: P
orlp
Saya tidak berpikir .ebarang itu sepadan - menggunakan o1 karakter lebih pendek seperti yang saya pikirkan.
isaacg
@isaacg Hak Anda. Lucunya, saya punya solusi 27 sebelum .esolusi 28. Tetapi solusi 27 berakhir dengan a )dan karena itu juga memiliki 28 byte. : oops:
Jakube
1
Saya memikirkan cara untuk menyimpan 2 karakter lain: Terjemahkan dari +@z1"KTA"ke "KTAZ", tetapi alih-alih menggunakan string secara langsung digunakan J"KTAZ"di awal dan +@z1Jke J.
isaacg
@isaacg Sangat pintar. Terima kasih. Btw. Saya berpikir cukup lama tentang membuat argumen ke-3 Xopsional (Hanya jika a dan b adalah string). Tapi saya tidak begitu yakin, jika Xab)harus mengevaluasi ke Xab_b(terbalik b, akan lebih baik untuk hal-hal seperti Xa"</\>") atau Xab+tbhb(b bergeser). Apa preferensi Anda?
Jakube
6

CJam, 34 33 byte

lS/_{)2$0='S+\#\"TQKA"_$er+}$W>#)

Algoritma

Logikanya sederhana. Saya memiliki jenis kustom yang terjadi, di mana saya pertama kali memberikan prioritas pada karakter kedua yang mewakili setelan. Dalam hal ini, Spades mendapat prioritas tertinggi dan kemudian suite yang pertama kali dilempar. Sisanya semua -1. Kemudian saya mengurutkan karakter pertama dengan bertukar Tdengan Adan Qdengan Kuntuk memiliki penyortiran leksikal.

Penjelasan kode

Pertama, mari kita lihat apa urutan leksikal dari nilai wajah kartu:

"23456789TJQKA"$

23456789AJKQT

Jadi, semua angka berada pada posisi yang benar. Jjuga pada posisi yang benar. Kita perlu bertukar Kdan Qdan Jdan Auntuk mendapatkan pesanan leksikal.

lS/_{)2$0='S+\#\"TQKA"_$er+}$W>#)
lS/                                 "Read an input line and split on spaces";
   _{                      }$       "Copy the array and sort it using this custom logic";
     )                              "Take off the last character of each hand.";
      2$0=                          "Get the suit of the first hand";
          'S+                       "Add Spades suit to it";
             \#                     "Get the index of the current hand suit.
                                     1 for Spades, 0 for first hand suit, -1 otherwise";
               \                    "Put face value of this hand on top of stack";
                "TQKA"              "Put string TQKA on stack";
                      _$            "Copy and sort. This essentially reverses the string
                                     TQKA to form AKQT. This is 1 byte shorter than _W%";
                        er+         "Swap T with A and K with Q and add to the
                                     suit index calculated previously";
                                    "After the above tuple, sorting will automatically
                                     convert the tuple to string and sort lexically";
                             W>     "Get the array containing only the last element";
                               #)   "Get the index of this hand in original set and
                                     increment to convert it to 1 based";

Cobalah online di sini

Pengoptimal
sumber
3

JavaScript (ES6), 112

Pindai daftar dan kembalikan posisi nilai tertinggi yang ditemukan.

Jalankan cuplikan untuk menguji (di Firefox)

F=t=>t.split(' ').map((c,i)=>(n='23456789TJQKA'.search(c[0])+(c[1]>'H'?40:c[1]==t[1]&&20))>m&&(m=n,r=i+1),m=0)|r

C.innerHTML=['TH QC JH 2H','KC 5S QS 9C','QD 2D TD 5D','9S 5D AD QS','3D 4C 3H JH','9S 4S TS JS','5H 9H 2C AD','5S 4C 3H QD'].map(h=>h+' -> '+F(h)).join('\n')
<pre id=C></pre>

edc65
sumber
3

Perl, 73 byte

#!perl -pl
/\B./;s/$&/P/g;y/TKA/IRT/;$_=reverse;@a=sort split;/$a[-1]/;$_=4-"@-"/3

Coba saya .

Mengonversi nama kartu sehingga urutan nilai permainan mengikuti urutan alfabet, lalu memilih yang tertinggi dengan mengurutkan dan mencarinya di string asli untuk posisi.

nutki
sumber
2

Ruby, 59 + 2 = 61

Dengan bendera baris perintah na, jalankan

p (1..4).max_by{|i|$F[i-1].tr($_[1]+'SJQKA','a-z').reverse}
histokrat
sumber
2

J, 47 byte

1+[:(i.>./)_3+/\16!@-]i.~'SXAKQJT9876543'1}~1&{

Pemakaian:

   (1+[:(i.>./)_3+/\16!@-]i.~'SXAKQJT9876543'1}~1&{) 'TH QC 9S 8S'
3

Metode:

  • Untuk setiap karakter input, kami menetapkan nilai berdasarkan posisinya di 'S[second char of input]AKQJT9876543'string. Karakter yang tidak ditemukan mendapatkan nilai last position + 1secara implisit. Karakter selanjutnya memiliki nilai yang jauh lebih kecil ( value=(16-position)!).
  • Hitung jumlah untuk triplet 3 input-char dan satu duplet (misalnya TH_ QC_ 9S_dan 8S).
  • Pilih indeks berbasis 1 dari nilai maksimal.

(J sayangnya tidak dapat membandingkan karakter atau string secara langsung. Ini hanya dapat memeriksa kesetaraan mereka yang mengesampingkan beberapa pendekatan lain untuk tantangan ini.)

Cobalah online di sini.

randomra
sumber
2

C #, 237

using System;namespace S{class P{static void Main(string[] a){var V="23456789TJQKA";int x=0;int y=0;var z=a[0][1];for(int i=0;i<4;i++){int q=V.IndexOf(a[i][0])+2;var w=a[i][1];q*=w==z?1:w=='S'?9:0;if(q>y){x=i;y=q;}}Console.Write(x+1);}}}

Cara kerjanya: Iterasi masing-masing tangan untuk menghitung "nilai" kartu .. simpan indeks bernilai tertinggi. Nilai kartu ditentukan sebagai pangkat kartu dikalikan dengan 0 jika bukan sekop atau suit pembuka, 1 jika itu adalah suit pembuka dan 9 jika itu adalah sekop tetapi bukan suit pembuka. (9 dipilih b / c 2 * 9 = 18> A = 14 & 9 adalah char tunggal)

CSCODE
sumber
1

Pyth, 36 33 byte

KczdhxKeo,x,ehK\SeNXhN"TKA""AYZ"K

Pendekatan yang cukup mudah, menggunakan penyortiran dengan fungsi tombol khusus, lalu menemukan indeks dengan nilai tertinggi.

orlp
sumber
Apakah Anda mencoba menghindari penyortiran dan hanya menemukan nilai tertinggi? Dalam JavaScript yang ternyata lebih pendek
edc65
@ edc65 Dalam Pyth tidak ada operasi untuk menemukan nilai tertinggi, hanya untuk menyortir. Tetapi dengan satu karakter ( e) Anda bisa mendapatkan elemen terakhir, jadi menemukan nilai tertinggi hanya mengurutkan diikuti dengan mendapatkan elemen terakhir.
orlp
Downvoter, mau jelaskan?
orlp
1

Pyth, 31 byte

hxczdeo}\SNo}@z1Zox"TJQKA"hNScz

Coba di sini.

Bagaimana itu bekerja:

Cara yang tepat untuk membaca prosedur ini adalah kembali ke depan. Prosedur mengurutkan kartu yang diinginkan ke akhir daftar, lalu menariknya keluar dan menemukan indeksnya dalam daftar asli.

  • cz: Ini menghasilkan daftar string kartu. c, chop, biasanya merupakan fungsi biner (arity 2), tetapi ketika dipanggil hanya dengan satu input, berfungsi sebagai .split()metode string.

  • S: Ini berlaku perilaku penyortiran normal, yang mengurutkan kartu bernomor lebih rendah sebelum yang lebih tinggi.

  • ox"TJQKA"hN: Ini memerintahkan kartu berdasarkan indeks ( x) dalam string "TJQKA"huruf pertama kartu ( hN). Untuk kartu dengan angka, huruf pertama tidak ditemukan, memberikan hasilnya -1. Karena fungsi sortir Pyth stabil, urutan kartu bernomor tidak terpengaruh.

  • o}@z1Z: Selanjutnya kita memesan apakah setelan kartu pertama dimainkan ( @z1) ada dalam kartu yang dimaksud. Sejak Truememilah di belakang False, ini mengirimkan kartu dari setelan utama ke belakang.

  • o}\SN: Ini sama dengan jenis sebelumnya, tetapi mengurutkan apakah surat itu Sada di kartu, mengirim sekop ke belakang.

  • hxczde: Ini mengekstraksi kartu terakhir yang diurutkan dengan cara ini ( e), menemukan indeksnya dalam daftar kartu ( xczd) dan kenaikannya sebesar 1 ( h), memberikan lokasi pemain yang diinginkan.

isaacg
sumber