ทำคะแนนในมือของหัวใจ


22

Heartsเป็นเกมไพ่ที่เล่นกลโดยผู้เล่น 4 คน เคล็ดลับแต่ละครั้งจะถูกนำโดยผู้เล่นที่เล่นไพ่สูงสุดของชุดสูทชั้นนำ ในตอนท้ายของแต่ละมือผู้เล่นจะต้องได้รับโทษตามการ์ดโทษที่พวกเขาได้รับ งานคือการกำหนดคะแนนภายใต้กฎหัวใจของ Microsoft

อินพุต

อินพุตคือ 4 รายการ (หรือสตริงที่มีการคั่น, อาร์เรย์, ฯลฯ ) แสดงบัตรโทษที่ผู้เล่นแต่ละคนจากทั้งสี่ บัตรโทษคือ

2♥, 3♥, 4♥, 5♥, 6♥, 7♥, 8♥, 9♥, 10♥, J♥, Q♥, K♥, A♥, Q♠

ซึ่งเราจะเป็นตัวแทนของ

2,  3,  4,   5,  6,  7,  8,  9,  10,  11, 12,  13,  1,  0

ตามลำดับ

เอาท์พุต

เอาท์พุทคือจุดโทษ 4 จุดที่เกิดขึ้นโดยผู้เล่น 4 คน (รายการ, สตริง, อาเรย์ ฯลฯ ) เกณฑ์การให้คะแนนมีดังนี้:

  • หัวใจแต่ละดวง ( ซึ่งแทนด้วยจำนวนเต็ม1ถึง13รวม) จะได้รับ 1 คะแนน
  • ราชินีแห่งโพดำ ( Q♠แสดงโดย0) ได้รับ 13 คะแนน
  • ข้อยกเว้น: หากผู้เล่นได้รับโทษทั้งหมด (เรียกว่าการยิงดวงจันทร์) จากนั้นเขาจะได้รับ 0 คะแนนในขณะที่ผู้เล่นคนอื่น ๆ ได้รับ 26 คะแนน

กรณีทดสอบ

[2, 8, 7, 1], [3, 4], [], [9, 5, 6, 0, 10, 11, 12, 13]     -->  4,  2,  0, 20
[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], [], [], [1]   --> 25,  0,  0,  1
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0], [], [], [] -->  0, 26, 26, 26

รหัสที่สั้นที่สุดในหน่วยไบต์ชนะ

คำตอบ:


3

CJam, 22 20 ไบต์

ขอบคุณ jimmy23013 สำหรับการบันทึก 2 ไบต์

{{XD?}f%1fb_26&1bf^}

บล็อกที่ไม่มีชื่อ (ฟังก์ชัน) ซึ่งรับรายการ 4 รายการเป็นอินพุตและส่งคืนรายการคะแนน

ลองออนไลน์!

คำอธิบาย

{      e# For each card...
  XD?  e#   Choose 1 if it's positive and 13 if it's zero.
}f%
1fb    e# Sum each hand.
_26&   e# Get the set intersection of the scores with 26. This gives [26]
       e# if someone shot the moon, and [] otherwise.
1b     e# Treat as base-1 digits, which gives 26 if someone shot the moon
       e# and zero otherwise.
f^     e# XOR each result with this number. This swaps zeros and 26s when 
       e# someone shot the moon and does nothing otherwise.

_26&1b. -2 ไบต์
jimmy23013

@ jimmy23013 Ahhhh, 1b... ฉันพยายามหาทางลัด[26]เข้า26และ[]ออก0แต่ไม่ทางใดก็เกิดขึ้นกับฉัน ขอบคุณ :)
Martin Ender

8

R, 85 77 74 ไบต์

function(x,z=sapply(x,function(x)sum(x>0)+any(x<1)*13))abs(z-any(z>25)*26)

ฟังก์ชั่นที่ไม่ได้ตั้งชื่อที่ใช้รายการ R เป็นอินพุต ทำงานโดยการนับจำนวนขององค์ประกอบ>0และเพิ่ม 13 ถ้าองค์ประกอบใด ๆ ในแต่ละเวกเตอร์<1(เช่นราชินีโพดำ) zและเก็บไว้เป็น

ถ้าองค์ประกอบใด ๆ ในการzเป็น>25ผลตอบแทนอื่นกลับมา26-zz

ลองใช้กับ R-fiddle


1
จะ26-zทำงานอย่างไร
u54112

@lastresort ใช่แน่นอน / facepalm
Billywob

4

C ++ 14, 158 ไบต์

ในฐานะแลมบ์ดาที่ไม่มีชื่อ:

[](auto c){typename decltype(c)::value_type r;int b=0;for(auto d:c){int q=0;for(auto i:d)q+=i?1:13;r.push_back(q);b+=q==26;}if(b)for(int&x:r)x=26-x;return r;}

ต้องมีvector<vector<int>>และส่งคืนvector<int>

Ungolfed:

[](auto c){
 typename decltype(c)::value_type r;   //result vector
 int b=0;                              //flag if one has all cards
 for(auto d:c){                        //over all decks
  int q=0;                             //count points
  for(auto i:d) q+=i?1:13;             //+13 for queen, +1 else
  r.push_back(q);                      //add to result
  b+=q==26;                            //possibly activate flag
 }
 if(b) for(int&x:r) x=26-x;            //if flag is set, mirror the results
 return r;
}

มีสักสองสามตัวอย่างสำหรับคุณ:

 auto r = std::vector<std::vector<int>>{{2,8,7,1},{3,4},{},{9,5,6,0,10,11,12,13}};
 auto s = std::vector<std::vector<int>>{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0},{},{},{}};
 auto t = std::vector<std::vector<int>>{{},{2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0},{},{1}};

4

Python 2, 75 72 71 ไบต์

i=[len(a)+12*(0in a)for a in input()]
print[[x,26-x][26in i]for x in i]

ใช้อินพุตเป็น [2, 8, 7, 1], [3, 4], [], [9, 5, 6, 0, 10, 11, 12, 13]


คุณช่วยตัวละคร 3 ตัวโดยใช้ 12 * [0in a] แทน [0,12] [0in a] ได้ไหม?
Costantino

@Costantino 12*(0in a)ฉันคิดว่าคุณหมายถึง
mbomb007

print[[x,26-x][26in i]for x in i]สั้นลงหนึ่งไบต์
mathmandan

3

PHP, 113 ไบต์

function h($a){foreach($a as&$b)$b=count($b)+12*in_array(0,$b);if(max($a)>25)foreach($a as&$n)$n=26-$n;return$a;}

ฟังก์ชั่นใช้อาร์เรย์ของอาร์เรย์ส่งกลับอาร์เรย์ของค่า


ประหลาดใจกับการทำแผนที่อาเรย์อื่น ๆ ใน PHP: ลูปกับรายการอ้างอิง waaay array_mapสั้นกว่า


3

Haskell, 62 59 56 ไบต์

f x|all(<26)x=x|0<1=map(26-)x
f.map(sum.map((13^).(0^)))

การใช้งาน:

> f.map(sum.map((13^).(0^))) $ [[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], [], [], [1]]
[25,0,0,1]

ฉันคิดว่าคุณสามารถเขียนเป็นf f n=13^0^n
xnor

@ xnor ฉันคิดว่าคุณพูดถูก บันทึก 3 ไบต์
อ่างทอง

ฉันคิดว่าการกำหนดf x|all(<26)x=x|0<1=map(26-)xและใช้งานแทนฟังก์ชันแลมบ์ดาจะช่วยประหยัดบางไบต์
Zgarb

@Zgarb ใช่คุณพูดถูกอีก 3 ไบต์
อ่างทอง

2

05AB1E ,26 22 21 ไบต์

ช่องว่างต่อท้ายต้องถูกลบออกจากอินพุตเพื่อให้ตีความเป็นอาร์เรย์ ตอนจบเป็นแรงบันดาลใจของคำตอบอื่น ๆ เมื่อใช้ (26-x) เมื่อผู้เล่นรวบรวมการ์ดโทษทั้งหมด

vy0å12*yg+})D26©åi(®+

v                    For each array
 y                   Push array on the stack
  0å                 Generate a boolean array indicating whether the queen of spades is at the same index in the original array
    12*              Multiply by 12 the value of the queen of spades
       yg+           Add the length of the array; the queen of spades gets her last point from this part
          }          End for
           )         Push an array of all evaluated scores
            D26©å    1 if there is a 26, 0 otherwise
                 i   If there is a 26
                  (®+ Mirror the array: for each element yield 26-element
                      Implicit end if
                      Implicitly print the score array

ลองออนไลน์!

มันยังคงดูเล่นกอล์ฟได้สวยด้วยค่าคงที่ซ้ำซ้อนและข้อความที่มีเงื่อนไข

รุ่นก่อนหน้านี้ 26 ไบต์

(หนึ่งไบต์สำหรับแต่ละจุดในค่าปรับสูงสุด)

ฉันตัดสินใจที่จะเก็บมันไว้เพราะความยาวของมันเหมาะกับความท้าทายนี้ในความคิดของฉัน :)

vyD0å12*sg+})D26©QDOi_®*ë\

ลองออนไลน์!


2

Python 3, 101 ไบต์

def s(a):r=[sum([(1,13)[c==0]for c in h])for h in a];s=(r,[(26,0)[s==26]for s in r]);return s[26in r]

รหัสเต็ม:

def score(hands):
    result = [sum([(1, 13)[card == 0] for card in hand]) for hand in hands]
    results = (result, [(26, 0)[score == 26] for score in result])
    return results[26 in result]

12*(c<1)+1คือ 2 (1,13)[c==0]ไบต์สั้นกว่า 26*(s>25)คือ 3 (26,0)[s==26]ไบต์สั้นกว่า
Mego

2

JavaScript (ES6), 82 80 77 72 70 69 67 ไบต์

บันทึก 2 ไบต์ขอบคุณ @Neil

f = 
s=>s.map(c=>c.map(t=>r+=t?1:13,r=0)|(b|=r>25,r),b=0).map(c=>b*26^c)

console.log(f.toString().length)
console.log(f([[2, 8, 7, 1], [3, 4], [], [9, 5, 6, 0, 10, 11, 12, 13]]));
console.log(f([[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], [], [], [1] ]));
console.log(f([[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13], [], [1], [] ]));
console.log(f([[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0], [], [], []]));
console.log(f([[],[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 0], [], []]));

ทำให้พังถล่ม

s=>s.map(                              // for each hand
 c=>c.map(                             // for each card
  t=>r+=t?1:13,                        // add value of card
 r=0)|(
  b=b|r>25,r                           // set flag if any hand scores 26 points
 ),
 b=0)
.map(c=>b?                             // for every card if a hand scored 26
  c?0:26                               // set every 0 hand to 26 and the 26 hand to 0
:c)                                    // otherwise do nothing

c=>b*26^cบันทึก 2 ไบต์
Neil

1

Pip , 28 ไบต์

27 ไบต์ของรหัส +1 สำหรับการ-pตั้งค่าสถานะ

Y{$+1+12*!*a}M Va26Ny?26-yy

รับอินพุตบนบรรทัดรับคำสั่งเป็นสตริงที่แทนรายการแบบซ้อนเช่น"[[2 8 7 1] [3 4] [] [9 5 6 0 10 11 12 13]]"(ไม่ต้องใช้เครื่องหมายคำพูดบน TIO) ลองออนไลน์!


1

Ruby, 59 ไบต์

->a{a.map{|h|a.max.size>13?h.min||26:h.size+12*h.count(0)}}

หรืออีกวิธีหนึ่งคือ

->a{a.map{|h|a.count([])>2?h.min||26:h.size+12*h.count(0)}}

หากมือเดียวมีไพ่ใด ๆ เราต้องการให้มือเปล่าได้ค่า 26 และมือที่มีไพ่จะได้ค่า 0 ฉันทำสิ่งนี้โดยการเรียกminมือ - นี่จะส่งกลับnilสำหรับอาร์เรย์ที่ว่างเปล่าแล้ว ฉัน||เป็น 26 ในกรณีอื่น ๆ ฉันนับจำนวนไพ่ในมือแล้วเพิ่ม 12 ลงใน Queen of Spades


0

สกาลา, 93 ไบต์

a=>{val% =a.map(_.map{case 0=>13;case _=>1}sum)
if(%toSet 26)%map{case 0=>26;case _=>0}else%}

การใช้งาน:

val f:(Seq[Seq[Int]]=>Seq[Int])=...
f(Seq(Seq(2, 8, 7, 1), Seq(3, 4), Seq(), Seq(9, 5, 6, 0, 10, 11, 12, 13)))

คำอธิบาย:

a=>{           //define an anonymou function with a parameter a
  val% =         //define % as...
    a.map(         //map each element of a...
      _.map{         //to each of the card
        case 0=>13     //replaced with its value
        case _=>1
      }
      sum            //and the sum of the values
    )
  if(            //if
    %toSet 26      //one player has all cards
  )
    %map{          //return % with...
      case 0=>26     //each 0 replaced with 26
      case _=>0      //and everything else (aka the 26) replaced 0
    }
  else           //else
    %              //return %
}

ฉันสามารถใช้%toSet 26แทน% contains 26เพราะSet's applyวิธีการเป็นcontainsและไม่ได้รับที่ดัชนีเช่นSeq' s

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