ไม่มีอะไรที่เหมือนกับเกมที่ดีของ ModTen


27

คำเตือน: ModTen เป็นเกมไพ่สวมซึ่งถูกสร้างขึ้นเพื่อวัตถุประสงค์เดียวของการท้าทายนี้

กฎของ ModTen

ModTenเล่นด้วยสำรับไพ่มาตรฐาน 52 ใบ เนื่องจากกฎทั้งหมดยังไม่ถูกคิดค้นเราจะมุ่งเน้นไปที่การจัดอันดับมือโดยเฉพาะ

แจ็ค & ทรีเหมาะ

มือที่ชนะใน ModTen กราฟิกจากวิกิพีเดีย

ค่าบัตร

บัตรมีค่าดังต่อไปนี้:

  • 2ถึง9 : มูลค่าที่คุ้มค่าของพวกเขา
  • สิบ : 0 จุด
  • แจ็ค : 3 คะแนน
  • ราชินีหรือราชา : 8 คะแนน
  • Ace : 9 คะแนน

คุณค่าของมือ

  • ModTenมือทำจากไพ่สองใบ ค่าฐานของไพ่นั้นได้มาจากการคูณค่าของไพ่ทั้งคู่เข้าด้วยกันและรักษาตัวเลขสุดท้ายเท่านั้น (เช่นการใช้โมดูโล 10)

    ยกตัวอย่างเช่นค่าของ7 ♥ - Q ♣คือ " 6 " เพราะ(7×8)พอควร10=6 6

  • กฎอื่น ๆ เท่านั้นในModTenคือการ์ดที่เหมาะสมมีค่ามากกว่าการ์ดที่ไม่เหมาะสม โดยการประชุมเราจะผนวก"s"เข้ากับค่าหากการ์ดทั้งคู่มีค่าเท่ากัน

    ตัวอย่างเช่นค่าของ9 ♠ - 5 ♠จะถูกบันทึกเป็น " 5s " เนื่องจาก(9×5)พอควร10=5และการ์ดมีความเหมาะสม

อันดับมือและผู้ชนะ

กฎข้างต้นส่งผลให้อันดับมือที่แตกต่างกัน 18 อันดับซึ่งสรุปไว้ในตารางต่อไปนี้จากแต้มสูงสุดถึงต่ำสุด ความน่าจะเป็นที่ได้รับข้อมูลเท่านั้น

เมื่อได้รับสองมือ, มือที่มีอันดับต่ำสุดชนะ หากมือทั้งสองข้างมีอันดับเท่ากันแสดงว่าเป็นเสมอ (ไม่มีการเสมอเบรก)

 hand rank | hand value(s) | deal probability
-----------+---------------+------------------
     1     | 9s            | 0.30%
     2     | 3s            | 0.60%
     3     | 1s            | 0.90%
     4     | 7s            | 1.21%
     5     | 5s            | 1.51%
     6     | 3             | 1.81%
     7     | 9             | 2.26%
     8     | 8s            | 2.71%
     9     | 6s            | 3.02%
    10     | 1 or 7        | 3.62% each
    11     | 2s or 4s      | 3.92% each
    12     | 5             | 4.98%
    13     | 0s            | 5.43%
    14     | 8             | 8.14%
    15     | 6             | 9.95%
    16     | 2             | 11.76%
    17     | 4             | 13.57%
    18     | 0             | 16.74%

ความท้าทาย

ให้ModTenสองมือส่งหนึ่งในสามค่าที่สอดคล้องกันที่คุณเลือกเพื่อบอกว่า:

  • ผู้เล่นคนแรกชนะ
  • ผู้เล่นคนที่สองชนะ
  • มันคือการเสมอกัน

ใช้กฎต่อไปนี้:

  • บัตรจะต้องได้รับการอธิบายจากตำแหน่งในกรณีบน ( 2, 3, ... , 9, T, J, Q, KหรือA) ตามด้วยชุดสูทในกรณีที่ต่ำกว่า ( c, d, hหรือsสำหรับสโมสร, เพชร, หัวใจและจอบ)
  • คุณสามารถใช้"10"แทนได้"T"แต่ห้ามทำการทดแทนอื่นใด
  • ตราบใดที่มีการปฏิบัติตามกฎข้างต้นคุณอาจใช้มือในรูปแบบที่สมเหตุสมผลและไม่คลุมเครือ คุณได้รับอนุญาตให้รับอันดับและสูทเป็นอักขระสองตัวที่แตกต่างกันแทนที่จะเป็นสตริงเดี่ยว

    บางรูปแบบอินพุตที่ถูกต้องคือ:

    • "7c Qh 8s Ks"
    • [["7c","Qh"], ["8s","Ks"]]
    • [[['7','c'], ['Q','h']], [['8','s'], ['K','s']]]
    • เป็นต้น
  • แทนการใช้ที่แตกต่างกัน 3 ค่าสอดคล้องส่งออกของคุณก็อาจจะเป็นเชิงลบ , บวกหรือศูนย์ โปรดระบุรูปแบบผลลัพธ์ที่ใช้ในคำตอบของคุณ

  • นี่คือรหัสกอล์ฟ

กรณีทดสอบ

ผู้เล่น 1 ชนะ

["Js","3s"], ["Ks","Kh"]
["7h","9h"], ["9s","7c"]
["Ah","5s"], ["Ts","8s"]
["Ts","8s"], ["Jh","2s"]
["4h","8s"], ["Qh","Ks"]

ผู้เล่น 2 ชนะ

["Th","8d"], ["6s","Kd"]
["Jc","5c"], ["3s","9s"]
["Jc","Jd"], ["9h","Ah"]
["2d","4d"], ["3h","3s"]
["5c","4c"], ["3c","2c"]

วาด

["Js","3s"], ["3d","Jd"]
["Ah","Ac"], ["3d","9s"]
["Qc","Kc"], ["6d","4d"]
["2d","3d"], ["3s","2s"]
["Ts","9c"], ["4h","5d"]

สิ่งที่เกี่ยวกับการใช้ enums เป็นอินพุต? Haskell มีระบบที่มีประสิทธิภาพประเภทสวย ; ฉันค่อนข้างแน่ใจว่าบางสิ่งเช่นนี้สามารถทำได้โดยตรง
wizzwizz4

นี่ไม่ใช่แฮสเคล แต่จะ{{J, s}, {3, s}}ไม่เป็นไร
wizzwizz4

1
@ wizzwizz4 ใช่มันไม่เป็นไร
Arnauld

2
ซึ่งอาจชัดเจนกว่าด้วย "ไพ่ในมือที่มีชุดจับคู่" แทนที่จะเป็น "ไพ่ที่เหมาะสม"
chrylis -on strike-

คำตอบ:


13

Python 3 , 114 110 ไบต์

lambda m,n:p(*n)-p(*m)
R=b"T 2J45UNK9RL<3SLM;QAK:O>=/678"
v=R.find
p=lambda i,s,j,t:R[s==t::2][v(j)*v(i)%10+3]

ลองออนไลน์!

@Arnauld เสนอแนวคิดในการรวมมูลค่าบัตรและจัดอันดับสตริงตาราง หลังจากพยายามบางครั้งฉันก็สามารถสร้างสตริงที่ผสานR="T 2J45UNK9RL<3SLM;QAK:O>=/678"ซึ่งมีความยาวเท่ากับสตริงค่าบัตรเดิม สตริงย่อยที่R[6:25]="UNK9RL<3SLM;QAK:O>=/"ทำหน้าที่เป็นตารางการจัดอันดับเช่นเดียวกับตารางการค้นหาค่าบัตร3, 9, A, และK Qการถอดรหัสค่า ASCII ของตารางอันดับใหม่มีผลการจัดอันดับเช่นเดียวกับตารางอันดับก่อนหน้า

การใช้สตริงไบต์เป็นอินพุตจะบันทึก 4 ไบต์

ใช้cmpในหลาม 2 สามารถลดวิธีการแก้ 102 ไบต์ที่แสดงโดยวิธีการแก้ปัญหาของ @ XNOR


Python 3 , 165 142 130 129 ไบต์

lambda m,n:p(*n)-p(*m)
v="T 23456789   J    QA        K".find
p=lambda i,s,j,t:ord("HC92FA51GAB4E893D760"[s==t::2][v(j)*v(i)%10])

ลองออนไลน์!

-23 ไบต์ขอบคุณ @Jonathan Allan

-2 ไบต์ขอบคุณ @ovs

-1 ไบต์ขอบคุณ @mypetlion

Ungolfed:

f = lambda hand1, hand2: get_rank(*hand2) - get_rank(*hand1)
def get_rank(v1, suit1, v2, suit2):
    get_card_value = "T 23456789   J    QA        K".find
    # rank_table = [[17,9,15,5,16,11,14,9,13,6],[12,2,10,1,10,4,8,3,7,0]]
    # rank_table = ("H9F5GBE9D6","C2A1A48370") # Base-18 encoding of ranks
    rank_table = "HC92FA51GAB4E893D760" # Interleaved base-18 encoding

    # ASCII-value decoding has the same ranking effect as base-18 decoding
    return ord(rank_table[suit1 == suit2::2][get_card_value(v2) * get_card_value(v1) % 10])

ฟังก์ชั่นfใช้สองข้อโต้แย้งที่เป็นตัวแทนของผู้เล่น 1 และผู้เล่น 2 มันจะส่งกลับค่าบวกลบหรือศูนย์ในกรณีของผู้เล่น 1 ชนะผู้เล่นที่ชนะ 2 หรือเสมอกัน แต่ละมือถูกเข้ารหัสเป็นสตริงเดียวเช่น "7cQh"


3
สวัสดี Joel ยินดีต้อนรับสู่ CGCC! แนวคิดที่ฉลาดมากที่แบ่งแถวลำดับมือออกเป็นสองส่วน! มาเลย!
640KB

1
@ Jonathan Allan ขอบคุณ ฉันได้รวบรวมแนวคิดของคุณโดยใช้แนวทางที่แตกต่างกันเล็กน้อย
โจเอล

1
คุณสามารถบันทึก 2 ไบต์โดยการจัดเก็บตารางอันดับในสายเดียว:"HC92FA51GAB4E893D760"[s==t::2]
OVS

1
และอีก4 ไบต์จะสั้นลงหากคุณยินดีเปลี่ยนเป็น Python 2 ( cmpไม่มีให้บริการใน Python 3)
ovs

1
คุณสามารถใช้str.findแทนstr.indexการบันทึกหนึ่งไบต์ ความแตกต่างที่ลักษณะการทำงานเพียงอย่างเดียวระหว่างสองวิธีคือindexโยนข้อผิดพลาดเมื่อองค์ประกอบที่ไม่พบในขณะที่ผลตอบแทนfind -1ดังนั้นมันจะไม่เป็นปัญหาสำหรับรหัสของคุณ
mypetlion

11

x86-16 ชุดประกอบ 87 83 ไบต์

เลขฐานสอง:

00000000: e807 0050 e803 005a 3ac2 ad2c 3092 ad2c  ...P...Z:..,0..,
00000010: 30bb 3501 3af4 7503 bb3f 01e8 0a00 92e8  0.5.:.u..?......
00000020: 0600 f6e2 d40a d7c3 b106 bf49 01f2 aee3  ...........I....
00000030: 038a 4504 c312 0a10 0611 0c0f 0a0e 070d  ..E.............
00000040: 030b 020b 0509 0408 0124 1a21 1b11 0003  .........$.!....
00000050: 0808 09                                  ...

แต่อย่างใด:

E8 010A         CALL GET_HAND           ; score first hand, ranked score into AL 
50              PUSH AX                 ; save score
E8 010A         CALL GET_HAND           ; score second hand 
5A              POP  DX                 ; restore first hand into DL 
3A C2           CMP  AL, DL             ; compare scores - result in CF, OF and ZF

            GET_HAND PROC               ; 4 char string to ranked score ("9s7c" -> 6)
AD              LODSW                   ; load first card string 
2C 30           SUB  AL, '0'            ; ASCII convert 
92              XCHG DX, AX             ; store in DX 
AD              LODSW                   ; load second card string 
2C 30           SUB  AL, '0'            ; ASCII convert 
BB 0139         MOV  BX, OFFSET R       ; first, point to non-suited table 
3A F4           CMP  DH, AH             ; is it suited?
75 03           JNZ  NO_SUIT 
BB 0143         MOV  BX, OFFSET RS      ; point to suited table 
            NO_SUIT: 
E8 012C         CALL GET_VALUE          ; get face card value in AL 
92              XCHG DX, AX             ; swap first and second cards 
E8 012C         CALL GET_VALUE          ; get face card value in AL 
F6 E2           MUL  DL                 ; multiply values of two cards 
D4 A0           AAM                     ; AL = AL mod 10
D7              XLAT                    ; lookup value in rank score table 
C3              RET 
            GET_HAND ENDP

            GET_VALUE PROC              ; get value of a card (2 -> 2, J -> 3, A -> 9)
B1 06           MOV  CL, 6              ; loop counter for scan
BF 014D         MOV  DI, OFFSET V       ; load lookup table 
F2/ AE          REPNZ SCASB             ; scan until match is found 
E3 03           JCXZ NOT_FOUND          ; if not found, keep original numeric value
8A 45 04        MOV  AL, BYTE PTR[DI+4] ; if found, get corresponding value 
            NOT_FOUND:
C3              RET                     ; return to program 
            GET_VALUE ENDP

R   DB 18, 10, 16, 6, 17, 12, 15, 10, 14, 7     ; unsuited score table
RS  DB 13, 3, 11, 2, 11, 5, 9, 4, 8, 1          ; suited score table
V   DB 'J'-'0','Q'-'0','K'-'0','A'-'0','T'-'0'  ; face card score table
    DB 3, 8, 8, 9, 0

การป้อนข้อมูลเป็นสตริงเช่นที่ชี้ในJs3sKsKh SIผลลัพธ์คือZF = 0 and SF = OF(ทดสอบด้วยJG) หากผู้เล่น 1 ชนะSF ≠ OF(ทดสอบด้วยJL) หากผู้เล่น 2 ชนะหรือZF(ทดสอบด้วยJE) หากเสมอ

เอาต์พุตโดยใช้โปรแกรมทดสอบ DOS:

ป้อนคำอธิบายรูปภาพที่นี่

ดาวน์โหลดและทดสอบMODTEN.COMสำหรับ DOS


7

05AB1E , 41 37 ไบต์

•V›{₆Ÿ&∊WÍj¸•19вyεø`Ës‘ߌQ‘ŽćS‡Pθ«}èÆ

-4 ไบต์ขอบคุณที่@Grimy

ป้อนข้อมูลเป็นรายการของรายการอักขระเช่นรูปแบบอินพุตตัวอย่างที่สามในคำอธิบายการท้าทาย คือ P1 7c Qhและ P2 จะป้อนข้อมูลเป็น8s Ks [[["7","c"],["Q","h"]],[["8","s"],["K","s"]]](และใช้"10"สำหรับ10)

ส่งออกจำนวนเต็มลบหากผู้เล่น 1 ชนะ; จำนวนเต็มบวกถ้าผู้เล่น 2 ชนะ หรือ 0 ถ้ามันเสมอ

ลองมันออนไลน์หรือตรวจสอบกรณีทดสอบทั้งหมด

คำอธิบาย:

V›{₆Ÿ&∊WÍj¸•  # Push compressed integer 36742512464916394906012008
 19в           # Convert it to base-19 as list:
               #   [18,10,16,6,17,12,15,10,14,7,13,3,11,2,11,5,9,4,8,1]
Iε             # Push the input, and map each of its hands to:
  ø            #  Zip/transpose the hand; swapping rows/columns
               #   i.e. [["8","s"],["K","s"]] → [[["8","K"],["s","s"]]
   `           #  Push them separated to the stack
    Ë          #  Check if the two suits in the top list are equal (1/0 for truthy/falsey)
    s          #  Swap to get the list with the two values
     ‘ߌQ     #  Push dictionary string "JAKEQ"
     ŽćS       #  Push compressed integer 39808
              #  Transliterate these characters to these digits
      P        #  Now take the product of the two values in the list
       θ       #  Only leave the last digit (basically modulo-10)
    «          #  And merge it to the 1/0
               #  (now we have the hand values of both players,
               #   where instead of a trailing "s" we have a leading 1)
             # After the map: index each value into the earlier created integer-list
               # (now we have the hand rank of both players)
   Æ           # And then reduce the resulting integers by subtracting
               # (after which the result is output implicitly)

ดู 05AB1E นี้เคล็ดลับของฉัน (ส่วนวิธีการใช้พจนานุกรมหรือไม่ วิธีการบีบอัดจำนวนเต็มขนาดใหญ่?และวิธีการบีบอัดรายการจำนวนเต็ม? )จะเข้าใจว่าทำไม•V›{₆Ÿ&∊WÍj¸•เป็น36742512464916394906012008, •V›{₆Ÿ&∊WÍj¸•19вคือ[18,10,16,6,17,12,15,10,14,7,13,3,11,2,11,5,9,4,8,1], ‘ߌQ‘เป็น"JAKEQ"และเป็นŽćS39808


คำถามที่ชัดเจนให้การป้อนข้อมูลTเป็น10ดังนั้นคุณก็สามารถลดลงTจากJTQKA(และใช้การบีบอัดจำนวนเต็ม 3889 แทน 30889) นอกจากนี้อาจจะT* ... + ... «
Grimmy

1
10T10nพอควร10=0T*...+...«

1
37 (ตอนนี้ใช้งานได้จริง!)
Grimmy

@Grimy Ah, การใช้พจนานุกรมเป็นอย่างดี!
Kevin Cruijssen

3

PHP ,212 185 178 149 ไบต์

while($p=$argv[++$x])$$x=ord(rjpfqlojngmckbkeidha[(($v=[J=>3,Q=>8,K=>8,A=>9])[$p[0]]?:$p[0])*($v[$p[2]]?:$p[2])%10+($p[1]==$p[3])*10]);echo${1}-${2};

ลองออนไลน์!

  • -7 ไบต์ขอบคุณ @ Night2!
  • -29 ไบต์โดย ASCII เข้ารหัสตารางแทนอาร์เรย์

อินพุตคือผ่านบรรทัดคำสั่ง เอาต์พุตไปSTDOUTเป็นลบหากผู้เล่น 1 ชนะบวกถ้าผู้เล่น 2 ชนะ0ถ้าเสมอ ตัวอย่าง:

$ php modten.php Js3s KsKh
-1

1
@ Night2 ฉันคิดว่าถ้าฉันก็เต็มใจที่จะให้เราผู้ประกอบการยานอวกาศ (ผมหมายถึงวิธีการที่คุณมักจะได้รับการใช้งานที่?) ผมสามารถ -2 ไบต์และเพิ่งกลับเชิงลบเชิงบวกหรือศูนย์แทน-1, หรือ1 0
640KB

ฉันประหลาดใจ (ในวิธีที่ดี) เพื่อดูผู้ประกอบการยานอวกาศในคำตอบก่อนหน้า
Night2

2

เยลลี่ขนาด 46 ไบต์

“T0J3Q8K8A9”yⱮZV€P$Eƭ€)%⁵UḌị“©N¿!Æßvṅ?żṀ’b18¤I

ลองออนไลน์!

โปรแกรมเต็มรูปแบบใช้เป็นอาร์กิวเมนต์สำหรับตัวอย่าง["7h","Ks"],["4s","Ts"]และพิมพ์ศูนย์หากผู้เล่นทั้งคู่วาดเป็นบวกถ้าผู้เล่น 1 ชนะและลบหากผู้เล่น 2 ชนะ


2

C (gcc) , 172 167 165 164 ไบต์

p(l,v)char*l,*v;{v="T 23456789   J    QA        K";return"A<92?:51@:;4>893=760"[(l[1]==l[3])+(index(v,l[2])-v)*(index(v,*l)-v)%10*2];}f(char*s){return p(s+5)-p(s);}

ลองออนไลน์!

2 ไบต์โกนออกแล้วต้องขอบคุณ @ceilingcat!

โดยทั่วไปจะเป็นพอร์ตของโซลูชัน Python3 ของ @ Joel แต่ไม่มีการเข้ารหัส base18 คาดว่าอินพุตเป็นสตริงเดียวโดยมีช่องว่างคั่นมือของผู้เล่นสองคนและส่งออกจำนวนเต็มซึ่งเป็นค่าบวกลบหรือศูนย์เพื่อระบุผู้เล่น 1 ชนะผู้เล่น 2 ชนะหรือหากเสมอ


2

Perl 6 , 101 100 94 88 ไบต์

-1 ไบต์ขอบคุณ Jo King

{[-] .map:{'HC92FA51GAB4E893D76'.ords[[*](.[*;0]>>.&{TR/JQKA/3889/})%10*2+[eq] .[*;1]]}}

ลองออนไลน์!

รับอินพุตเป็นf(((<J ♠>, <3 ♠>), (<10 ♠>, <K ♥>)))ใช้10สำหรับสิบ ส่งกลับค่า <0 หากผู้เล่น 1 ชนะ,> 0 ถ้าผู้เล่น 2 ชนะ 0 ถ้าเป็นการจับสลาก

คำอธิบาย

{
  [-]  # subtract values
  .map:{  # map both hands
    'HC92FA51GAB4E893D76'.ords[  # lookup rank in code point array
      [*](  # multiply
        .[*;0]  # card ranks
        >>.&{TR/JQKA/3889/}  # translate J,Q,K,A to 3,8,8,9
      )
      %10*2  # mod 10 times 2
      +[eq] .[*;1]  # plus 1 if suited
    ]
  }
}

1

Charcoal , 97 ไบต์

≔”)¶&sNψU↓”ζF¹³F¹³F⁻⁴⁼ικ⊞υ⁺÷λ³⊗﹪Π⁺§ζι§ζκχ≔”A↘τ[⁵PkxτG”ε≔⁰δF⟦θη⟧≦⁻№υ⁺⁼§ι¹§ι³⊗﹪Π⁺§ζ⌕ε§ι⁰§ζ⌕ε§ι²χδIδ

ลองออนไลน์! การเชื่อมโยงคือการใช้รหัสเวอร์ชันอย่างละเอียด รับอินพุตเป็นสองสายอักขระ 4 ตัวอักษรเช่นQcKc 6d4dและแสดงจำนวนเต็มที่ลงนาม คำอธิบาย:

≔”)¶&sNψU↓”ζ

สตริงที่บีบอัด2345678903889แสดงถึงค่าบัตร

F¹³F¹³

วนซ้ำค่าที่เป็นไปได้แต่ละคู่

F⁻⁴⁼ικ

วนซ้ำไพ่แต่ละใบที่เป็นไปได้ เราสามารถสรุปได้ว่าไพ่ใบแรกมีสูท 3 ดังนั้นชุดไพ่ใบที่สองสามารถอยู่ในช่วงตั้งแต่ 0 ถึง 3 เว้นแต่ว่าค่าจะเหมือนกันซึ่งในกรณีนี้จะมีช่วงตั้งแต่ 0 ถึง 2 เท่านั้น

⊞υ⁺÷λ³⊗﹪Π⁺§ζι§ζκχ

คำนวณคะแนนที่ดัดแปลงของมือซึ่งเป็นค่าของไพ่สองเท่าและ 1 ถ้าชุดนั้นเหมือนกัน (เช่นไพ่ใบที่สองมีชุดที่ 3)

≔”A↘τ[⁵PkxτG”ε

สตริงที่บีบอัด23456789TJQKAหมายถึงอักขระการ์ด บัตรอินพุตจะถูกค้นหาในสตริงนี้จากนั้นตำแหน่งจะถูกใช้เพื่อจัดทำดัชนีลงในสตริงแรกเพื่อรับค่าของการ์ด

≔⁰δ

เริ่มต้นผลลัพธ์เป็น 0

F⟦θη⟧

วนรอบมือทั้งสองข้าง

≦⁻№υ⁺⁼§ι¹§ι³⊗﹪Π⁺§ζ⌕ε§ι⁰§ζ⌕ε§ι²χδ

คำนวณคะแนนที่แก้ไขของมือและทำให้ความถี่และลบผลลัพธ์จากสิ่งนี้

Iδ

เอาท์พุทความแตกต่างความถี่



0

Perl 5 -p , 107 ไบต์

$a=A;y/ATJQK/90388/;${$a++}=substr"IAG6HCFAE7D3B2B59481",($1eq$3).$&*$2%10,1while/.(.) (.)(.)/g;$_=$A cmp$B

ลองออนไลน์!

การป้อนข้อมูล:

As 4d,Th 8c

(อันที่จริงเครื่องหมายจุลภาคสามารถเป็นอักขระใดก็ได้)

เอาท์พุท:

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