คนแคระและเหรียญ


32

สถานการณ์:

Mคนแคระหลายคนพบหีบสมบัติของก๊อบลินที่มีNเหรียญทองและต้องแบ่งมัน เนื่องจากกฎโบราณเกี่ยวกับการจัดสรรปล้นทรัพย์ให้แก่โจรสลัดตามลำดับอาวุโสดาวแคระที่เก่าแก่ที่สุดควรได้รับหนึ่งเหรียญมากกว่าดาวแคระที่เก่าที่สุดถัดไปและอื่น ๆ เพื่อที่ดาวแคระที่อายุน้อยที่สุดจะได้รับM-1เหรียญน้อยกว่าดาวแคระที่เก่าที่สุด นอกจากนี้คนแคระไม่ต้องขว้างเหรียญใด ๆ (เช่นไม่มีเหรียญติดลบกับคนแคระ)

ช่วยคนแคระแบ่งเหรียญด้วยวิธีนี้หรือบอกพวกเขาว่ามันเป็นไปไม่ได้

รหัสผู้ชนะจะต้องตอบถูกต้องเสมอ (ความท้าทายนี้เป็นกำหนด) และปฏิบัติตามทั่วไปกฎ

อินพุต

คุณจะได้รับจำนวนเต็ม N (3 ≤ N ≤ 1,000) สำหรับจำนวนเหรียญและจำนวนเต็ม M (3 ≤ M ≤ N) สำหรับคนแคระจำนวนหนึ่งคั่นด้วยช่องว่าง

เอาท์พุต

หากไม่สามารถแบ่งเหรียญในแบบที่คนแคระต้องการให้พิมพ์ -1 (ลบหนึ่ง) มิฉะนั้นให้พิมพ์จำนวนเหรียญที่คนแคระแต่ละคนจะได้รับจากตัวเก่าที่สุดถึงอายุน้อยที่สุด แยกตัวเลขด้วยช่องว่าง

ตัวอย่าง :

อินพุต

3 3

เอาท์พุต

2 1 0

อินพุต

9 3

เอาท์พุต

4 3 2

อินพุต

7 3

เอาท์พุต

-1

อินพุต

6 4

เอาท์พุต

3 2 1 0

4
คุณพลาด "โจรสลัด"
Rawling


3
ดีหา @Raystafarian บางทีเมื่อครูได้รับการแก้ปัญหาทั่วไปสำหรับคนแคระ M แทนเพียง 3 เขา / เขาจะรู้ว่าผู้ใช้ตอบคำถาม :) - โดยเฉพาะอย่างยิ่งหากนักแก้ปัญหานั้นอยู่ใน J.
ProgrammerDan

ทำการบ้านหรือไม่มันเป็นคำถามที่ดี Smurfing!
เลเวลริเวอร์เซนต์

คำตอบ:


18

เจ - 32 29 28 25

ไม่ สั้นกว่าโซลูชัน J อื่น ๆ แต่ และใช้ความคิดที่แตกต่าง

(]{.[:i:-:@-.@]-%)/ ::_1:

คำตอบสำหรับจำนวนเหรียญอันดับคำพังเพยที่สูงที่สุดจะได้รับเป็นเพียงN/M+(M-1)/2(ถ้ามันเป็นจำนวนเต็ม) -:@-.@]-%เราสร้างเชิงลบของการนี้ จากนั้นi:สร้างอาเรย์แบบนั้น2 1 0 _1 _2เพื่อโต้แย้ง_2และเรานำองค์ประกอบ M


1
+1 i:สำหรับการใช้งานที่ยอดเยี่ยมของ คุณสามารถบันทึกอีกสามถ่านโดยการเขียน%แทน[%]และใช้แทน-.@] (1-])
algorithmshark

@algorithmshark ขอขอบคุณเพื่อน J ผู้ชื่นชอบ!
swish

1
ไม่สามารถ +1 เนื่องจาก @swish ดูเหมือนว่าจะอยู่กับพวกโนมส์ที่เราเพิ่งปล้น ;)
TheConstructor

11

J - 30 ตัวอักษร

สนุกมากกับการเล่นกอล์ฟ หลายสิ่งหลายอย่างออกมาอย่างเรียบร้อย

((+/@s~i.[){ ::_1:s=.+/&i.&-)/

คำอธิบาย:

  • /- ใช้จำนวนเต็มคั่นด้วยช่องว่างเป็นอาร์กิวเมนต์และเลื่อนฟังก์ชันระหว่างพวกเขา กล่าวคือให้พิจารณา N อาร์กิวเมนต์ด้านซ้ายของฟังก์ชันในวงเล็บ(...)และ M คืออาร์กิวเมนต์ที่ถูกต้อง

  • i.&-- ลบ ( -) จากนั้นใช้จำนวนเต็ม ( i.) โดยปกติเมื่อคุณทำสิ่งที่ชอบที่คุณได้รับi.5 0 1 2 3 4เมื่อใดก็ตามที่i.ได้รับจำนวนลบมันจะกลับรายการรายการนั้น ดังนั้นเช่นจะให้i._54 3 2 1 0

  • s=.+/&- ดำเนินการข้างต้นกับแต่ละอาร์กิวเมนต์ ( &) จากนั้นสร้างตารางเพิ่ม ( +/) จากอาร์เรย์เหล่านี้ ตอนนี้เรามีตารางที่แต่ละแถวมีการแจกจ่ายเหรียญที่เป็นไปได้ให้คนแคระ M แม้ว่าอาจจะไม่ใช่เมื่อมีเหรียญ N ในที่สุดคำกริยาการสร้างตารางนี้มีประโยชน์มากเราจะเรียกมันsและใช้มันอีกครั้งในภายหลัง

  • +/@s~- ตอนนี้เราใช้sอีกครั้ง แต่เราสลับ ( ~) ลำดับของอาร์กิวเมนต์เพื่อให้เราย้ายตาราง นี่เป็นวิธีตีกอล์ฟที่จะหาผลรวมของแต่ละแถวหลังจากสร้างตาราง ( +/@) โดยเกี่ยวข้องกับวิธีที่ J สรุปรายการหลายมิติ

  • i.[ - ในรายการผลรวมนี้เราค้นหาอาร์กิวเมนต์ซ้ายไปที่กริยานั่นคือ N หาก N เป็นรายการเราจะได้ดัชนีนั้น: มิฉะนั้นเราจะได้ความยาวของรายการซึ่งเป็นดัชนีที่ไม่ถูกต้อง

  • { ::_1:- sตอนนี้เราพยายามที่จะใช้ดัชนีจะดึงออกมาจากแถวตารางใน {จะโยนข้อผิดพลาดโดเมนหากดัชนีไม่ถูกต้องดังนั้นในกรณีนั้นเราจะตรวจจับข้อผิดพลาด ( ::) และส่งคืน -1 ( _1:) นี้จัดการทุกอย่าง เนื่องจากเราใช้i.&-ก่อนหน้านี้การกระจายเหรียญจะเรียงตามลำดับจากน้อยไปมากตามต้องการ

การใช้งาน:

   ((+/@s~i.[){ ::_1:s=.+/&i.&-)/ 9 3
4 3 2
   ((+/@s~i.[){ ::_1:s=.+/&i.&-)/ 7 3
_1
   ((+/@s~i.[){ ::_1:s=.+/&i.&-)/ 6 4
3 2 1 0
   ((+/@s~i.[){ ::_1:s=.+/&i.&-)/ 204 17
20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4

การป้อนข้อมูล9 3ควรจะกลับไม่ได้4 3 2 -1ดูเหมือนว่ามีการขนย้ายในการใช้งานตัวอย่างของคุณ?
ProgrammerDan

@ProgrammerDan ขอบคุณไม่ทราบว่า ฉันพิมพ์ตัวอย่างผิด 9 3ให้4 3 2และ7 3ให้_1ตามที่คาดไว้
algorithmshark

เห็นตัวแก้ไขและ +1 อย่างเหมาะสม: D ฉันควรดูเป็น J ดูดี
ProgrammerDan

7

R - 71 70 67 66 65 ตัวอักษร

s=scan();m=s[2];x=s[1]-sum(1:m);cat(if(x%%m|-m>x)-1 else x/m+m:1)

Ungolfed:

s = scan()    # Reads N and M by stdin.
m = s[2]
x = s[1] - m*(m-1)/2
cat(if (x %% m | x < -m) -1 else x/m + m:1)

วิธีการแก้:

ถ้าMคือจำนวนของดาวแคระลำดับของทองคำที่ต้องชำระจะแยกเป็นสองซีรีส์ ชุดแรกที่ลงท้ายด้วยศูนย์: M-1, ... , 2, 1, 0 และชุดที่คงที่ของ c, c, ... , c ผลรวมของชุดแรกคือ M * (M-1) / 2 เสมอ ดังนั้นหากส่วนที่เหลือ (x = N - M * (M-1) / 2) สามารถแบ่งได้โดยไม่เหลือ (โมดูโลเท่ากับ 0) แต่ละคนแคระได้รับ x / M บวกส่วนของซีรีส์ที่ลดลง

การใช้งาน:

> s=scan()
1: 10 4
3: 
Read 2 items
> m=s[2]
> x = s[1] - m*(m-1)/2
> cat(if (x %% m || x<0) -1 else x/m + (m-1):0)
4 3 2 1

-1 คำถามต้องเขียนโปรแกรมที่สมบูรณ์ไม่ใช่ฟังก์ชั่น ดูmeta.codegolf.stackexchange.com/a/1146/8766
80551

@ user80551 คุณพูดถูก ตอนนี้ฉันแก้ไขส่วนย่อย: ตอนนี้ใช้อินพุตที่คั่นด้วยช่องว่าง ผลลัพธ์ยังไม่แสดง '[1]' อีกต่อไป
lambruscoAcido

1
คุณสามารถบันทึกตัวละครอื่นที่แทนที่m*(m+1)/2ด้วยsum(1:m)
Brian Diggs

@ Brian Thx ฉันจะแก้ไขรหัสของฉัน!
lambruscoAcido

4

PHP (187)

มันเป็นความพยายามครั้งแรกของฉันในการเล่นกอล์ฟและฉันรู้ว่ามันจะดีกว่า แต่ก็ยัง :)

แข็งแรงเล่นกอล์ฟ:

<?php
$b=fgets(STDIN);list($c,$d)=explode(' ',$b);if((($d&1)AND($c%$d==0))OR($c%$d==$d/2)){for($e=floor($c/$d)+floor($d/2);$e>floor($c/$d)-round($d/2);$e--){echo"$e ";}}else{die('-1');}?>

Ungolfed:

<?php
$a = fgets(STDIN);
list($coins, $dwarves) = explode(' ', $a);
if ((($dwarves & 1) AND ($coins % $dwarves == 0)) OR ($coins % $dwarves == $dwarves / 2)) {
    for (
        $i = floor($coins / $dwarves) + floor($dwarves / 2);
        $i > floor($coins / $dwarves) - round($dwarves / 2);
        $i--
    ) {
        echo "$i ";
    }
}
else { 
  die('-1');
}
?>

ดำเนินการในเปลือก

แนวคิดพื้นฐาน:

เหรียญสามารถแยกออกได้โดยกฎเหล่านี้หากหนึ่งในนั้นเป็นจริง:

  1. คนแคระมีจำนวนคี่และเหรียญสามารถแบ่งได้โดยคนแคระโดยไม่เหลือ
  2. คนแคระเป็นเลขคู่และเหรียญที่เหลืออยู่หลังจากแบ่งเหรียญ / คนแคระเท่ากับครึ่งหนึ่งของจำนวนคนแคระ

ถ้าเป็นเช่นนั้นเราจะหาฐานเฉลี่ยต่อคนแคระ (ACPD) แต่เราต้องเริ่มจากจุดสูงสุดและเอาท์พุทจนกว่าจะถึงจุดต่ำสุด ดังนั้นเราจึงวนรอบด้วยตัวนับเริ่มต้นจาก ACPD + จำนวนของคนแคระที่เหลือไปจนถึงระดับสูงสุดและดำเนินต่อไปจนกว่าเราจะไปถึง ACPD - จำนวนคนแคระที่เหลือจนถึงระดับล่าง

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

ปัญหาที่เกิดขึ้น: ทำงานกับจำนวนเหรียญต่ำเกินไปซึ่งหมายความว่าคนแคระบางคนจะถูกตีและปล้นรายได้อันมีค่าของพวกเขา และนี่เป็นเรื่องน่าเศร้า หรืออย่างน้อยถ้าคุณชอบคนแคระ

วิธีแก้ปัญหา :

  1. ลองนึกถึงวิธีการคำนวณจำนวนเงินต่ำสุดเพื่อให้การคำนวณไม่ได้จบลงด้วยคนแคระในฝุ่น
  2. ออกแบบคนแคระที่ไม่โลภ

โซลูชันที่ชาญฉลาด :

เหรียญเป็นโลหะ ทำให้คนแคระละลายพวกเขาทั้งหมดแล้วโยนพวกเขาในจำนวนที่น้อยลง / มากขึ้นของเหรียญดังนั้นพวกเขาจึงสามารถแบ่งแยกได้ในทุกกรณี

ทางออกที่ฉลาดที่สุด :

ขโมยภูเขาของพวกเขาเปลี่ยนชื่อตัวเองเป็นสม็อกและเก็บทุกอย่างไว้เพื่อตัวคุณเอง ท้ายที่สุดทำไมคุณต้องมายุ่งกับคนแคระที่ไม่พอใจ?


4

Python 3 (100)

ใช้แนวคิดเดียวกันกับ@Geitsแต่สอดคล้องกับข้อกำหนดอินพุตและเอาต์พุต

n,m=map(int,input().split())
κ,ρ=divmod(n-m*(m-1)//2,m)
x=[-1]if ρ else range(κ,κ+m)[::-1]
print(*x)

ขอบคุณสำหรับหัวขึ้น. ไม่ได้สังเกตเห็นการแยกช่องว่างที่เพิ่มเข้าไปในข้อกำหนดการป้อนข้อมูล
Geobits

สิ่งเหล่านั้นอาจเป็น 100 ตัวอักษร แต่เนื่องจากชื่อตัวแปรกรีกจะต้องมี 105 ไบต์
Jonathan Frech

4

Python 3 - 109 107 103 102 90 93

ใช้แนวคิดเดียวกันกับ Evpok แต่มีการปรับปรุงหลายอย่าง

n,m=map(int,input().split())
k=n/m+m/2
a=int(k)
print(*(range(a,a-m,-1),[-1])[k-a-.5or~a>-m])

การปรับปรุงคือ:

  1. กำจัดพื้นที่หลังจากที่อื่นและก่อน '' 1 ตัวอักษร
  2. กำจัดเครื่องหมาย '' split () ภายในเนื่องจากการแยกช่องว่างเป็นค่าเริ่มต้น 3 ตัวอักษร
  3. การลด x ด้วย 1 จะเป็นการเปลี่ยน -1 เป็น +1 ภายใน divmod จากนั้นเปลี่ยนฟังก์ชันช่วงเพื่อใช้ตัวเลือกคำสั่งที่กลับรายการของช่วง 3 ตัวอักษร
  4. แก้ไข: ... ถ้า ... อื่น ... เปลี่ยนเป็น ... และ ... หรือ ... 2 ตัวอักษร
  5. แก้ไข: Divmod ทำให้ชัดเจนลบ r 4 ตัวอักษร
  6. แก้ไข: ลบแล้ว x, m // n ใช้อย่างชัดเจน 1 ตัวอักษร
  7. แก้ไข: ใช้นิพจน์ที่ติดดาวแทน '' .join (map (str, ... )), เพิ่ม x เพื่อหลีกเลี่ยงการพิมพ์ซ้ำ () 12 ตัวอักษร
  8. แก้ไข: ฉันรู้ว่าฉันอนุญาตให้มอบเหรียญติดลบให้แก่คนแคระได้ ฉันเปลี่ยนรหัสเพื่อหลีกเลี่ยงปัญหานี้

ทำได้ดีมันเป็นคำแนะนำ :) ฉันเปลี่ยนคำตอบเพื่อตัดพื้นที่ที่ไม่จำเป็นออกไป แต่เคล็ดลับในการบันทึกของคุณ[::-1]ดีกว่าโซลูชันของฉัน +1
Evpok

ฉันอาจจะหายไปบางอย่าง แต่ฉันนับ 93 ไบต์แทน 94
Jonathan Frech

3

Python 3 - 114

n,m=map(int,input().split(' '))
r=range(m);n-=sum(r)
if n%m<1:
 for x in r:print(m-x+n//m-1,end=' ')
else:print -1

ทำงานโดยการตรวจสอบถ้าN-(M*(M-1)/2)หารเท่า ๆ Mกันโดย ใหม่สำหรับงูใหญ่ดังนั้นคำแนะนำใด ๆ ที่ชื่นชม

ตัวอย่าง Ideone.com

Input:
735 30
Output:
39 38 37 36 35 34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10

เคยมีรุ่น Python 3 ที่รองรับprintสไตล์คำสั่งของ Python 2 หรือไม่? หรือบรรทัดสุดท้าย ( else:print -1) ไม่ส่งผลให้เกิดข้อผิดพลาดอย่างไร
Jonathan Frech

3

C # - 322

using System;using System.Linq;namespace D{class P{static void Main(string[]args){int n=Convert.ToInt16(args[0]);int m=Convert.ToInt16(args[1]);bool b=false;int q=n/2+1;g:b=!b;int[]z=new int[m];for(int i=0;i<m;i++){z[i]=q-i;}if(z.Sum()==n)foreach(int p in z)Console.Write(p+" ");else{q--;if(b)goto g;Console.Write(-1);}}}}

คะแนนแย่มาก แต่ฉันใช้วิธีอื่นและใช้goto:)

ฉันจะสั้นลงในภายหลัง


1
แน่นอนคุณสามารถร่นทุกคนโทรไปเพียงConvert.ToInt16 int.Parseคุณสามารถประกาศตัวแปรที่กำหนดไว้ล่วงหน้าด้วยvar(แทนเช่นint[]) params argsบรรทัดคำสั่งของคุณไม่จำเป็นที่จะเรียกว่า using C = Consoleและคุณก็สามารถประเภทนามแฝงที่ใช้บ่อยเช่น ฉันคิดด้วยว่าสำหรับวิธีแก้ปัญหาที่ยาวนานนี้ดีกว่าที่จะนำเสนอด้วยการเว้นวรรคบรรทัดเหมือนเดิมมากกว่าการบันทึกอักขระเพียงสองสามตัว โอ้และฉันไม่ได้จริงๆว่าทำไมgotoดีกว่าทางเลือกที่นี่ทั้ง ...
Aaronaught

3

Java 210

class A { public static void main(String[] a){int d=Integer.parseInt(a[0]),c=Integer.parseInt(a[1]);if (2*c%d==0) for (int i=0;i<d;i++) System.out.print((((1+(2*c/d)-d)/2)+i)+" "); else System.out.print(-1);}}

2
ยินดีต้อนรับสู่ PPCG ฉันเห็นว่าคุณมีช่องว่างมากมายที่สามารถลบออกได้
pastebin.com slash 0mr8spkT

คุณสามารถตัดช่องว่างออกไปอีกมากเพื่อให้คำตอบของคุณออกไปอีกเล็กน้อย - ตัวอย่างclass A{public static void main(String[]a)ถูกต้องและช่วยให้คุณประหยัด 3 ตัว หลังจากแต่ละifรอบและรอบแต่ละforลบช่องว่าง ... ฯลฯ
ProgrammerDan

มันบ้าว่า "ประชาชนเป็นโมฆะคงหลัก (S" เป็นส่วนหนึ่งตราบเท่าที่ว่าการแก้ปัญหาทั้ง J :)
โรเบิร์ตแกรนท์

3

R: 77 73 70 ตัวอักษร

a=scan();r=a[2]:1-1;while((n=sum(r))<a[1])r=r+1;cat(`if`(n>a[1],-1,r))

สร้างเวกเตอร์ที่ไปจาก (M-1) ถึง 0 และเพิ่ม 1 ให้กับแต่ละหมายเลขจนกว่าผลรวมจะไม่ด้อยกว่า N หากมันเหนือกว่าเอาต์พุต -1 จะส่งออกเวกเตอร์

เว้าแหว่งและ ungolfed เล็กน้อย:

a=scan()   #Reads in stdin (by default numeric, space-separated)
r=a[2]:1-1 #Creates vector (M-1) to 0
while(sum(r)<a[1])r=r+1 #Increments all member of vector by 1 until sum is not inferior to N
cat( #Outputs to stdout
    `if`(sum(r)>a[1], -1, r) #If superior to N: impossible, returns -1
    )

ตัวอย่างการใช้งาน:

> a=scan();r=a[2]:1-1;while((n=sum(r))<a[1])r=r+1;cat(`if`(n>a[1],-1,r))
1: 9 3
3: 
Read 2 items
4 3 2
> a=scan();r=a[2]:1-1;while((n=sum(r))<a[1])r=r+1;cat(`if`(n>a[1],-1,r))
1: 7 3
3: 
Read 2 items
-1
> a=scan();r=a[2]:1-1;while((n=sum(r))<a[1])r=r+1;cat(`if`(n>a[1],-1,r))
1: 204 17
3: 
Read 2 items
20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4

2

จูเลียอายุ 45 ปี

f(n,m)=(x=n/m-m/2+1/2;x%1==0?[x+m-1:-1:x]:-1)
julia> f(6,4)'
1x4 Array{Float64,2}:
 3.0  2.0  1.0  0.0

แค่พีชคณิตสักหน่อยเอาฉันไปนานกว่าที่ควรจะเป็น


2

JavaScript - 76

สังเกตว่า k + (k - 1) + ... + (k - (M - 1)) = M (k - (M - 1) / 2) การตั้งค่านี้เท่ากับ N ให้ k = N / M + (M -1) / 2 สำหรับจำนวนสูงสุด หากนี่เป็นจำนวนเต็มดังนั้น k% 1 == 0 และจำนวนที่เราต้องการคือ k, k - 1, ... , k - (M - 1)

ฉันอาจจะเขียนนี้สั้นลงในภาษาอื่น แต่ยังไม่มีวิธีแก้ปัญหา JS ดังนั้นที่นี่เป็น:

N=3;M=3;if((r=N/M+(M-1)/2)%1)console.log(-1);else while(M--)console.log(r--)

ทำงานในคอนโซล

อินพุตตัวอย่าง:

N=3;M=3;if((r=N/M+(M-1)/2)%1)console.log(-1);else while(M--)console.log(r--)

เอาท์พุท:

3
2
1 

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

N=6;M=4;if((r=N/M+(M-1)/2)%1)console.log(-1);else while(M--)console.log(r--)

เอาท์พุท:

3
2
1
0

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

N=7;M=3;if((r=N/M+(M-1)/2)%1)console.log(-1);else while(M--)console.log(r--)

ผลลัพธ์: -1

console.log ที่แย่เกินไปก็นานแล้วที่จะสะกดคำ :) ขออภัยที่การประกาศl=console.log.bind(console)ไม่ทำให้สั้นลงและl=console.logไม่ทำงาน

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

"N=3;M=3;if((r=N/M+(M-1)/2)%1)console.log(-1);else while(M--)console.log(r--)".length

เอาท์พุท:

76

คุณสามารถใช้c=consoleและc.log()ย่อให้สั้นลง
2428118

2

Golfscript, 35

~:M.(*2/-.M%{;-1}{M/M+,-1%M<' '*}if

มันทำงานอย่างไร

9 3ในตัวอย่างต่อไปนี้เข้าเป็น

          # STACK: "9 3"
~         # Interpret the input string.
          # STACK: 9 3
:M        # Store the top of the stack (number of dwarves) in variable `M'.
.         # Duplicate the top of the stack.
          # STACK: 9 3 3
(         # Decrement the top of the stack.
          # STACK: 9 3 2
*         # Multiply the topmost elements of the stack.
          # STACK: 9 6
2/        # Divide the top of the stack by `2'.
          # STACK: 9 3
          # So far, we've transformed `M' into `M*(M-1)/2', which is the minimum amount of
          # coins all dwarves together will get. This number comes from the fact that the
          # youngest dwarf will get at least 0 coins, the next at least 1 coin, etc., and
          # 0 + 1 + ... + (M - 1) = M*(M-1)/2.
-         # Subtract the topmost elements of the stack.
          # STACK: 6
          # The remaining coins have to get reparted evenly to all dwarves.
.         # Duplicate the top of the stack.
          # STACK: 6 6
M%        # Calculate the top of the stack modulus `M'.
          # STACK: 6 0
{         # If the modulus is positive, the remaining coins cannot get reparted evenly.
    ;-1   # Replace the top of the stack by `-1'.
}
{         # If the modulus is zero, the remaining coins can get reparted evenly.
    M/    # Divide the top of the stack by `M'.
          # STACK: 2
          # This is the number of coins all dwarves will get after giving 1 to the second
          # youngest, etc.
    M+    # Add `M' to the top of the stack.
          # STACK: 5
    ,     # Replace the top of the stack by an array of that many elements.
          # STACK: [ 0 1 2 3 4 ]
          # The rightmost element is the number of coins the oldest dwarf will get.
    -1%   # Reverse the array.
          # STACK: [ 4 3 2 1 0 ]
    M<    # Keep the leftmost `M' elements.
          # STACK: [ 4 3 2 ]
          # There are only `M' dwarves.
    ' '*  # Join the array, separating by spaces.
          # STACK: "4 3 2"
}if

1

Delphi XE3 (176)

uses SysUtils;var d,c,i:integer;begin read(c,d);for I:=1to d-1do c:=c-i;if c mod d>0then writeln(-1)else begin c:=c div d;for I:=d-1downto 0do write(IntToStr(i+c)+' ');end;end.

มันทำงานอย่างไร.

อ่าน 2 จำนวนเต็มเหรียญและคนแคระ
ลดความต่างของดาวแคระลง
หากตัวแบ่งส่วนที่เหลือแคระ> 0 เป็นไปไม่ได้
ได้รับส่วนแบ่งเท่ากันต่อคนแคระในวงของคนแคระ -1 ถึง 0 และพิมพ์ dwarfIndex + ส่วนแบ่งเท่ากัน

Ungolfed

uses SysUtils;
var
  d,c,i:integer;
begin
  read(c,d);
  for I:=1to d-1do
    c:=c-i;
  if c mod d>0then
    writeln(-1)
  else
  begin
    c:=c div d;
    for I:=d-1downto 0do
      write(IntToStr(i+c)+' ');
  end;
end.

1

Mathematica 65

ฟังก์ชัน,, gสร้างลำดับที่เพิ่มขึ้นหนึ่งความยาว m, จาก 0 ถึง n และตรวจสอบว่าส่วนใด ๆ ของมันรวมกันเป็น m หากสำเร็จลำดับจะถูกส่งคืน มิฉะนั้นจะส่งคืน -1

ลำดับจะทำโดยPartitioning รายการ {0,1,2,3 … m} ลงในรายการย่อยที่เป็นไปได้ทั้งหมดของจำนวนเต็ม n ที่ต่อเนื่องกัน

แน่นอนมีวิธีที่มีประสิทธิภาพมากขึ้นเพื่อให้ได้ผลเหมือนกัน แต่วิธีที่ฉันได้พบต้องใช้รหัสเพิ่มเติม

n_~g~m_:=If[(s=Select[Partition[0~Range~n,m,1],Tr@#==n&])=={},-1,s]

ตัวอย่าง

g[9, 3]

{{2, 3, 4}}


g[3, 3]

{{0, 1, 2}}


g[7, 3]

-1


g[705, 3]

{{234, 235, 236}}


g[840, 16]

{{45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60}}


g[839, 16]

-1


1

C 131

#include <edk.h>
main(int a,char **v){int j=atoi(*++v),k=atoi(*++v)-j*(j-1)/2;k<0||k%j?j=1,k=-1:k/=j;while(j--)printf("%d ",k+j);}

Ungolfed

#include <edk.h> //Shortest standard header including stdio.h and stdlib.h
main(int a,char **v)
{
    int j=atoi(*++v),k=atoi(*++v)-j*(j-1)/2;

    k<0||k%j?j=1,k=-1:k/=j;  // If youngest dwarf gets < 0 or amount not equally divisible then set values such that ...

    while(j--)printf("%d ",k+j); // ... loop prints out correct values
}

คอมไพล์ด้วยคำเตือนเนื่องจาก main ไม่มีประเภท หากนี่ไม่ถูกต้องในกฎของกอล์ฟฉันจะต้องเพิ่มตัวละครห้าตัว


1

งูเห่า - 198

เว็บไซต์คอบร้า

class P
    def main
        x,y=Console.readLine.split
        a,b=x to int,y to int
        l=[]
        t=n=0
        for i in b,t+=i
        while (t+=b)<=a,n+=1
        for i in b,l.insert(0,i+n)
        print if(t-b<>a,-1,l.join(" "))

อธิบาย:

class P
    def main

จำเป็นต้องใช้รหัสในการทำงาน

        x,y=Console.readLine.split
        a,b=x to int,y to int

ใช้อินพุตและเก็บเป็นaและb

        l=[]
        t=n=0

เริ่มต้นรายการเอาท์พุทlและเริ่มต้นเงินที่ต้องการทั้งหมดtและจำนวนเหรียญเพื่อเพิ่มไปยังกองแคระแต่ละอันn

        for i in b,t+=i

ค้นหามูลค่าเงินที่ต่ำที่สุดที่เป็นไปได้ซึ่งจะส่งผลให้คนแคระทุกคนมีจำนวนเหรียญที่อนุญาตในกองของพวกเขา

        while (t+=b)<=a,n+=1

กำหนดจำนวนเหรียญที่จะเพิ่มในแต่ละกองเพื่อให้เงินที่ต้องการทั้งหมดคือ> = ไปยังเงินทั้งหมดที่มี

        for i in b,l.insert(0,i+n)

เติมรายชื่อด้วยกองเงินขนาดต่างๆ

        print if(t-b<>a,-1,l.join(" "))

เอาท์พุทอย่างใดอย่างหนึ่ง-1หรือlขึ้นอยู่กับว่าเงินที่ต้องการทั้งหมดเท่ากับเงินทั้งหมด



-1

Python ( 100 96 94):

คำตอบที่ดีรอบคะแนน ไม่มากไปกว่านี้ แต่ตอนนี้จะสั้นลง

def f(n,m):a=range(m)[::-1];b=n-sum(a);c=b/m;d=[i+c for i in a];return(d,-1)[-1in d or c*m!=b]

Ungolfed:

def f(n,m):
 a = range(m)[::-1]
 b = sum(a)
 c = (n-b)/m
 if c * m != n-b: return -1
 d = [i+c for i in a]
 return (d,-1)[-1 in d or c!=n-b]
 if -d in d or c*m!=n-b:
  return -1
 return d

เอาท์พุท:

def f(n,m):a=range(m)[::-1];b=sum(a);c=(n-b)/m;d=[i+c for i in a];return (d,-1)[-1 in d or c*m!=n-b]

f(3,3)
Out[2]: [2, 1, 0]

f(9,3)
Out[3]: [4, 3, 2]

f(7,3)
Out[4]: -1

f(6,4)
Out[5]: [3, 2, 1, 0]

2
สิ่งนี้ไม่เป็นไปตามข้อกำหนดการป้อนข้อมูล
Austin Henley

-1 คำถามต้องเขียนโปรแกรมที่สมบูรณ์ไม่ใช่ฟังก์ชั่น ดูmeta.codegolf.stackexchange.com/a/1146/8766
80551
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.