เรียงลำดับตัวเลขตามการนับของไบนารี 1


35

เป้าหมาย

เขียนฟังก์ชั่นหรือโปรแกรมเรียงลำดับอาร์เรย์ของจำนวนเต็มตามลำดับจากมากไปน้อยด้วยจำนวนของ 1 ในการเป็นตัวแทนไบนารีของพวกเขา ไม่จำเป็นต้องมีเงื่อนไขการเรียงลำดับรอง

ตัวอย่างรายการที่เรียงลำดับ

(ใช้จำนวนเต็ม 16 บิต)

  Dec                Bin        1's
16375   0011111111110111        13
15342   0011101111101110        11
32425   0111111010101001        10
11746   0010110111100010         8
28436   0000110111110100         8
19944   0100110111101000         8
28943   0000011100011111         8
 3944   0000011111101000         7
15752   0011110110001000         7
  825   0000000011111001         6
21826   0101010101000010         6

อินพุต

อาเรย์ของจำนวนเต็ม 32 บิต

เอาท์พุต

อาร์เรย์ของจำนวนเต็มเดียวกันที่เรียงลำดับตามที่อธิบายไว้

เกณฑ์การให้คะแนน

นี่คือรหัสกอล์ฟสำหรับจำนวนไบต์ที่น้อยที่สุดที่จะเลือกในเวลาหนึ่งสัปดาห์


2
คุณไม่ได้พูดถึงอย่างชัดเจน แต่จำเป็นต้องเรียงลำดับจากมากไปน้อยหรือไม่
นิค T

3
คุณพูดถูกฉันพลาด คนอื่น ๆ ก็ลดหลั่นกันไปดังนั้นเราจะยึดมันไว้
Hand-E-Food

ฉันคิดว่าหมายเลขสุดท้าย (21826) ได้รับการแปลงผิด ตาม Windows เครื่องคิดเลขของฉันก็ 0101 0101 0100 0010 ไม่ 0010 1010 1100 0010.
Nzall

ขอบคุณสำหรับการแก้ไขเหล่านั้น มันแปลก ๆ ประมาณ 21826 เพราะฉันใช้ Excel เพื่อแปลงตัวเลขเป็นเลขฐานสอง ฉันสงสัยเกี่ยวกับส่วนที่เหลือตอนนี้
Hand-E-Food

วิธีการแก้ปัญหาโดยใช้คำแนะนำการประกอบและ popcount?
eiennohito

คำตอบ:


27

J (11)

(\:+/"1@#:)

นี่คือฟังก์ชั่นที่รับรายการ:

     (\:+/"1@#:) 15342 28943 16375 3944 11746 825 32425 28436 21826 15752 19944
16375 15342 32425 28943 11746 28436 19944 3944 15752 825 21826

หากคุณต้องการตั้งชื่อมันมีค่าใช้จ่ายอักขระพิเศษหนึ่งตัว:

     f=:\:+/"1@#:
     f 15342 28943 16375 3944 11746 825 32425 28436 21826 15752 19944
16375 15342 32425 28943 11746 28436 19944 3944 15752 825 21826

คำอธิบาย:

  • \:เรียงลำดับลง
  • +/: ผลรวมของ
  • "1: แต่ละแถวของ
  • #:: การเป็นตัวแทนไบนารี

5
@ ak82 เป็น APL เวอร์ชัน ASCII
John Dvorak

3
@JanDvorak แปลก ๆ ; มีการเปลี่ยนแปลงเล็กน้อย: jsoftware.com/papers/j4apl.htm (ดูหัวข้อภาษา)
James Wood

3
นอกจากนี้ยังมี\:1#.#:ที่บันทึกไม่กี่ไบต์
ไมล์

17

JavaScript, 39

อัปเดต:ตอนนี้สั้นกว่าทับทิม

x.sort(q=(x,y)=>!x|-!y||q(x&x-1,y&y-1))

40

x.sort(q=(x,y)=>x&&y?q(x&x-1,y&y-1):x-y)

คำอธิบาย:

q เป็นฟังก์ชันแบบเรียกซ้ำ ถ้า x หรือ y เป็น 0 มันจะส่งกลับx-y(จำนวนลบถ้า x เป็นศูนย์หรือจำนวนบวกถ้า y เป็นศูนย์) มิฉะนั้นจะลบบิตต่ำสุด ( x&x-1) จาก x และ y และทำซ้ำ

รุ่นก่อนหน้า (42)

x.sort(q=(x,y)=>x^y&&!x-!y+q(x&x-1,y&y-1))

นี่ฉลาดจริงๆ! ฉันยังคงพยายามที่จะปิดใจของฉันไปรอบ ๆ
mowwwalker

ไม่ควร~yทำงานแทน-!y?
แปรงสีฟัน

@toothbrush เงื่อนไขสิ้นสุดคือ x หรือ y เป็น 0 ซึ่งในกรณีนี้นิพจน์!x|-!yจะไม่เป็นศูนย์ ~ไม่พอดีเนื่องจากไม่มีอินพุตสำหรับอินพุตจำนวนมาก (รวมถึงศูนย์)
คัดลอก

ทุกคนสามารถช่วยเหลือฉันในกรณีที่การเรียงลำดับรองจะต้องโปรด?
Manubhargav

15

ทับทิม 41

f=->a{a.sort_by{|n|-n.to_s(2).count(?1)}}

ทดสอบ:

a = [28943, 825, 11746, 16375, 32425, 19944, 21826, 15752, 15342, 3944, 28436];
f[a]
=> [16375, 15342, 32425, 11746, 28436, 28943, 19944, 15752, 3944, 21826, 825]

2
ง่าย เข้าใจได้ สั้น. ความรุ่งโรจน์สำหรับการแก้ปัญหานี้
Pierre Arlaud


8

เสียงกระเพื่อมสามัญ 35

logcountส่งคืนจำนวน 'on'-bits ในจำนวน สำหรับรายการlเรามี:

(sort l '> :key 'logcount)
CL-USER> (sort (list 16375 15342 32425 11746 28436 19944 28943 3944 15752 825 21826) '> :key 'logcount)
;=> (16375 15342 32425 11746 28436 19944 28943 3944 15752 825 21826)

ในฐานะที่เป็นฟังก์ชั่นแบบสแตนด์อโลนและสิ่งที่ฉันจะยึดไบต์นับบน

(lambda(l)(sort l'> :key'logcount))

7

Python 3 90 77 72 67 ตัวอักษร

โซลูชันของเรารับอินพุตจากบรรทัดคำสั่งและพิมพ์ตัวเลขตามลำดับจากน้อยไปหามาก (67 ตัวอักษร) หรือจากน้อยไปมาก (66)

เรียงลำดับจากมากไปน้อย

print(sorted(input().split(),key=lambda x:-bin(int(x)).count("1"))) # 67

ขอบคุณ@danieroสำหรับคำแนะนำในการใช้เครื่องหมายลบในการนับ 1 เพื่อย้อนกลับแทนที่จะใช้ชิ้นเพื่อย้อนกลับอาร์เรย์ในตอนท้าย! วิธีนี้ช่วยประหยัด 5 อักขระอย่างมีประสิทธิภาพ

เพียงเพื่อประโยชน์ในการโพสต์เวอร์ชั่นสำหรับการเรียงลำดับ (ซึ่งเป็นครั้งแรกที่เราทำ) จะมีอักขระน้อยลง

เรียงลำดับขึ้น :

print(sorted(input().split(),key=lambda x:bin(int(x)).count("1"))) # 66

ขอบคุณ@Bakuriuสำหรับคำแนะนำkey = lambda x … ; D


ดังนั้น0จะเป็นส่วนหนึ่งของผลลัพธ์ของคุณเสมอ ไม่ถูกต้อง
daniero

ฉันไม่เห็นสิ่งใดในคำถามที่ห้ามไม่ให้ฉันใส่ค่า
Jetlef

ฉัน: "อาร์เรย์ของจำนวนเต็มเดียวกันเรียงตามที่อธิบายไว้" ;) นอกจากนี้ทำไมไม่ใช้เพียงแค่raw_input()วางอักขระบางตัว?
daniero

1
@daniero แก้ไขแล้ว การสลับไปใช้ Python 3 (คำตอบของ Python 2 มีอยู่แล้วต้องมีความคิดสร้างสรรค์!) อนุญาตให้ฉันใช้อินพุต ()บันทึกอักขระสองตัว (ต้องเพิ่มสองตัวเพราะวงเล็บที่ต้องการโดยprint () )
Jetlef

คุณสามารถวางภายใน[] sortedด้วยเอาต์พุตของโปรแกรมนี้คือจำนวน 1s ในตัวเลขในอินพุตที่เรียงลำดับ แต่คุณควรเอาท์พุทจำนวนที่คุณได้รับในอินพุตเรียงลำดับโดยใช้จำนวน1s สิ่งที่ชอบ: print(sorted(input().split(), key=lambda x:bin(int(x)).count('1')))จะถูกต้อง
Bakuriu

7

JavaScript [76 ไบต์]

a.sort(function(x,y){r='..toString(2).split(1).length';return eval(y+r+-x+r)})

โดยที่aเป็นอาร์เรย์ของตัวเลข

ทดสอบ:

[28943,825,11746,16375,32425,19944,21826,15752,15342,3944,28436].sort(function(x, y) {
    r = '..toString(2).split(1).length';
    return eval(y + r + -x + r);
});

[16375, 15342, 32425, 19944, 11746, 28943, 28436, 15752, 3944, 21826, 825]

คุณช่วยบอก..ได้ไหมว่ามันทำงานอย่างไร ความเข้าใจของฉันคือว่าถ้าx = 5แล้วeval(x + r)จะกลายเป็นeval(5..toString(2).match(/1/g).length)ซึ่งก็คือผมคิดว่าไม่ถูกต้อง ขอบคุณ
Gaurang Tandon

1
@GaurangTandon มันไม่ได้เป็น อย่างที่คุณทราบใน JS ทุกอย่างยกเว้นตัวอักษรเป็นวัตถุ และตัวเลข ดังนั้นในทางทฤษฎี (และจริง) คุณอาจได้รับคุณสมบัติหรือวิธีการเรียกร้องของใด ๆ ที่ไม่ใช่ตัวอักษรผ่านจุดสัญกรณ์ที่คุณทำหรือ'string'.length [1,2,3].pop()ในกรณีของตัวเลขคุณอาจทำเช่นเดียวกัน แต่คุณควรจำไว้ว่าหลังจากแยกจุดเดียวแล้ว parser จะค้นหาส่วนที่เป็นเศษส่วนของจำนวนที่คาดว่าจะมีค่าลอยตัว (ตาม123.45) ถ้าคุณใช้จำนวนเต็มคุณควรจะ "บอก" แยกวิเคราะห์ว่าส่วนที่เป็นเศษส่วนเป็นที่ว่างเปล่า, 123..method()การตั้งจุดพิเศษก่อนที่อยู่สถานที่ให้บริการ:
VisioN

1
คุณสามารถบันทึกสองไบต์โดยการดึงค่าศูนย์และถือว่าส่วนที่เหลือเป็นตัวเลขทศนิยม แทนที่ด้วยmatch(/1/g).length replace(/0/g,"")
DocMax

@VisioN ขอบคุณ! เรียนรู้สิ่งใหม่
Gaurang Tandon

1
a.sort(function(x,y){r='..toString(2).match(/1/g).length';return eval(y+r+-x+r)})
l4m2


6

k [15 ตัวอักษร]

{x@|<+/'0b\:'x}

ตัวอย่างที่ 1

{x@|<+/'0b\:'x}19944, 11746, 15342, 21826, 825, 28943, 32425, 16375, 28436, 3944, 15752

16375 15342 32425 28436 28943 11746 19944 15752 3944 825 21826

ตัวอย่างที่ 2 (ตัวเลขทั้งหมดคือ 2 ^ n -1)

{x@|<{+/0b\:x}'x}3 7 15 31 63 127

127 63 31 15 7 3

5

Mathematica 39

IntegerDigits[#,2] แปลงเลขฐาน 10 เป็นรายการ 1 และ 0

Tr สรุปตัวเลข

f@n_:=SortBy[n,-Tr@IntegerDigits[#,2]&]

กรณีทดสอบ

f[{19944, 11746, 15342, 21826, 825, 28943, 32425, 16375, 28436, 3944, 15752}]

{16375, 15342, 32425, 11746, 19944, 28436, 28943, 3944, 15752, 825, 21826}


ฉันชอบการใช้ Tr [] ในการตีกอล์ฟ
Michael Stern

5

Java 8 - 87/113 81/111 60/80 60/74/48 ตัวอักษร

นี่ไม่ใช่โปรแกรมภาษาจาวาที่สมบูรณ์ แต่เป็นเพียงฟังก์ชั่น (เมธอดที่แน่นอน)

มันถือว่าjava.util.Listและjava.lang.Long.bitCountนำเข้าและมี 60 ตัวอักษร:

void s(List<Long>a){a.sort((x,y)->bitCount(x)-bitCount(y));}

หากไม่อนุญาตสิ่งที่นำเข้าล่วงหน้านี่คืออักขระ 74 ตัว:

void s(java.util.List<Long>a){a.sort((x,y)->x.bitCount(x)-x.bitCount(y));}

เพิ่มมากขึ้น 7 staticตัวอักษรถ้ามันจะต้องว่ามันควรจะเป็น

[4 ปีต่อมา] หรือหากคุณต้องการมันอาจเป็นแลมบ์ดา (ขอบคุณ @KevinCruijssen สำหรับคำแนะนำ) ด้วยขนาด 48 ไบต์:

a->{a.sort((x,y)->x.bitCount(x)-x.bitCount(y));}

ทำไมคุณถึงทำไม่ได้Integer.bitCount(x)<Integer.bitCount(y)?-1:1;? คุณต้องการ-1,0,1พฤติกรรมหรือไม่
Justin

นอกจากนี้เป็นไปได้ไหมที่จะแทนที่<Integer>ด้วยที่ว่าง?
Justin

นอกจากนี้คุณยังสามารถใช้Longที่ประหยัดพื้นที่บาง :)
RobAu

นอกจากนี้ a.sort((x,y)->Long.bitCount(x)-Long.bitCount(y));
RobAu

1
@KevinCruijssen ขอบคุณ ฉันเคยชินกับการใช้อินสแตนซ์ตัวแปรเพื่อเรียกใช้เมธอดแบบสแตติกเป็นวิธีปฏิบัติที่ไม่ดีที่ฉันลืมว่าคอมไพเลอร์ยอมรับสิ่งนั้น
Victor Stafusa

4

Python 2.x - 65 ตัวอักษร (ไบต์)

print sorted(input(),key=lambda x:-sum(int(d)for d in bin(x)[2:]))

ที่จริงแล้วมี 66 ตัวอักษร 65 ถ้าเราทำมันเป็นฟังก์ชั่น

f=lambda a:sorted(a,key=lambda x:-sum(int(d)for d in bin(x)[2:]))

การสาธิตใน Bash / CMD:

echo [16, 10, 7, 255, 65536, 5] | python -c "print sorted(input(),key=lambda x:-sum(int(d)for d in bin(x)[2:]))"

คุณสามารถเปลี่ยนsum(int(d)for d in bin(x)[2:])เป็นsum(map(int,bin(x)[2:]))
Elisha

1
หรือแม้กระทั่ง:print sorted(input(),key=lambda x:-bin(x).count('1'))
เอลีชา

4

Matlab, 34

ป้อนข้อมูลใน 'a'

[~,i]=sort(-sum(dec2bin(a)'));a(i)

ใช้งานได้กับตัวเลขที่ไม่ติดลบ


4

C - 85 ไบต์ (108 106 ไบต์)

รุ่นพกพาบน GCC / Clang / ทุกที่__builtin_popcountสามารถใช้ได้ (106 ไบต์):

#define p-__builtin_popcount(
c(int*a,int*b){return p*b)-p*a);}
void s(int*n,int l){qsort(n,l,sizeof l,c);}

รุ่นย่อ MSVC แบบเดียวที่ทำงานได้อย่างย่อไม่สามารถพกพาได้ (85 ไบต์):

#define p __popcnt
c(int*a,int*b){return p(*b)-p(*a);}
s(int*n,int l){qsort(n,l,4,c);}         /* or 8 as needed */

  • ขึ้นบรรทัดใหม่ครั้งแรกที่รวมอยู่ในจำนวนไบต์เนื่องจาก#defineตัวอื่นไม่จำเป็น

  • ฟังก์ชั่นการโทรเป็นs(array, length)ไปตามข้อกำหนด

  • สามารถ hardcode sizeofในเวอร์ชันพกพาเพื่อบันทึกอีก 7 ตัวอักษรเช่นเดียวกับคำตอบ C อื่น ๆ ฉันไม่แน่ใจว่าอันไหนที่มีค่ามากที่สุดในแง่ของอัตราส่วนความยาวต่อการใช้งานคุณเป็นผู้ตัดสินใจ


2
sizeof lบันทึกเป็นไบต์ คนที่น่าเกลียดอย่างน่ากลัว#define p-__builtin_popcount(สามารถช่วยผู้อื่นได้
ugoren

@ugoren ขอบคุณสำหรับเคล็ดลับ! ตัวประมวลผลล่วงหน้าเป็นแฮ็คฉันไม่รู้ว่ามันเป็นไปได้ น่าเศร้าที่มันใช้ไม่ได้กับ MSVC แต่ทุกไบท์นับ!
โทมัส

4

PowerShell v3, 61 58 53

$args|sort{while($_){if($_-band1){1};$_=$_-shr1}}-des

ScriptBlock สำหรับSort-Objectcmdlet ส่งคืนอาร์เรย์ 1 สำหรับแต่ละ 1 ในการแทนเลขฐานสองของตัวเลข Sort-Objectเรียงลำดับรายการตามความยาวของอาร์เรย์ที่ส่งคืนสำหรับแต่ละหมายเลข

ในการดำเนินการ:

script.ps1 15342 28943 16375 3944 11746 825 32425 28436 21826 15752 19944

มันใช้งานได้ มันทำงานยังไง? วิธีมหัศจรรย์ '.' มาถึง 'ตามความยาวของอาเรย์'?
mazzy

The '.' เรียกใช้งานสคริปต์บล็อกที่มาหลังจากนั้น คำสั่ง sort เรียงลำดับตามเอาต์พุตของ scriptblock ด้านนอก ตอนนี้ฉันรู้แล้วว่าไม่จำเป็นต้องใช้สคริปต์บล็อกภายใน ดูการแก้ไข
Rynant

$f={ซ้ำซ้อน, while-> for, -band1-> %2, -des-> -dและลูกกอล์ฟอื่น ๆ ก็เป็นที่ชัดเจน. คุณอธิบายวิธีการทำงานได้$args|sort{@(1,1,...,1)}ไหม มันใช้งานได้! วิธีการจัดเรียงเปรียบเทียบอาร์เรย์โดยไม่ชัดเจน.Count? อ่านที่ไหนดี? ขอบคุณ!
mazzy

1
@ มาซี่คุณพูดถูกฉันถอดบิตซ้ำซ้อนออกแล้ว มันคือการเรียงลำดับเริ่มต้นของ Sort-Object cmdlet ดู: help Sort-Object -Parameter propertyฉันไม่รู้ว่าที่กำหนดคุณสมบัติการเรียงลำดับเริ่มต้นสำหรับประเภท แต่สำหรับอาร์เรย์มันคือการนับหรือความยาว
Rynant

คาดหมายได้ดี. แต่$args|sort{while($_){if($_-band1){$_};$_=$_-shr1}}-desให้ผลลัพธ์ที่ผิด Countดังนั้นจึงเป็นไม่ได้ มันน่าสนใจสุด ๆ. ขอบคุณอีกครั้ง.
mazzy

3

ECMAScript 6, 61

ถือว่าzเป็นอินพุต

z.sort((a,b)=>{c=d=e=0;while(++c<32)d+=a>>c&1,e+=b>>c&1},e-d)

ทดสอบข้อมูล

[28943,825,11746,16375,32425,19944,21826,15752,15342,3944,28436].sort(
    (a,b)=>{
        c=d=e=0;
        while(++c<32)
            d+=a>>c&1,e+=b>>c&1
    },e-d
)

[16375, 15342, 32425, 11746, 19944, 28436, 28943, 15752, 3944, 21826, 825]

ขอบคุณแปรงสีฟันสำหรับทางออกที่สั้นกว่า


1
ฉันเพิ่งลองวิธีแก้ปัญหาของคุณ แต่มันไม่ทำงาน มันไม่ได้เรียงลำดับตัวเลข
แปรงสีฟัน

@toothbrush woops ขอบคุณสำหรับการจับที่ควรจะทำงานตอนนี้
แดนนี่

การทำงานที่ดี! ฉันชอบมัน.
แปรงสีฟัน

1
61 ไบต์เท่านั้น: z.sort((a,b)=>{c=d=e=0;while(++c<32)d+=a>>c&1,e+=b>>c&1},e-d)(และขอขอบคุณสำหรับการโหวต)
แปรงสีฟัน

1
โซลูชันของฉันมีขนาดเท่ากับของคุณแล้ว!
แปรงสีฟัน

3

R , 132 96 94 88 84 75 73 53 51 ไบต์

-20 ต้องขอบคุณการใช้ J.Doe -2 ขอบคุณ Giuseppe มากขึ้น

function(x)x[order(colSums(sapply(x,intToBits)<1))]

โพสต์ต้นฉบับของฉัน:

pryr::f(rev(x[order(sapply(x,function(y)sum(as.double(intToBits(y)))))]))

ลองออนไลน์!

ฉันลองใช้วิธีการที่แตกต่างกันหลายอย่างก่อนที่ฉันจะลงไปสู่ผลลัพธ์

วิธีเมทริกซ์:สร้างเมทริกซ์คอลัมน์สองคอลัมน์หนึ่งคอลัมน์ที่มีเวกเตอร์อินพุตหนึ่งในผลรวมของการแทนฐานสองจากนั้นฉันเรียงลำดับตามผลรวมของไบนารี

function(x){m=matrix(c(x,colSums(sapply(x,function(y){as.integer(intToBits(y))}))),nc=2,nr=length(x));m[order(m[,2],decreasing=T),]}

ไม่ใช่เมทริกซ์:ตระหนักแล้วฉันสามารถโยนฟังก์ชันเมทริกซ์และสร้างเวกเตอร์ของค่าไบนารีรวมหาพวกเขาสั่งพวกเขาแล้วใช้ค่าที่สั่งซื้อเพื่อจัดเรียงเวกเตอร์อินพุตอีกครั้ง

function(x){m=colSums(sapply(x,function(y){as.integer(intToBits(y))}));x[order(m,decreasing=T)]}

การเปลี่ยนแปลงเล็กน้อย

function(x){m=colSums(sapply(x,function(y)as.double(intToBits(y))));x[order(m,decreasing=T)]}

การเปลี่ยนแปลงเล็กน้อยเพิ่มเติมการแปลงทุกสิ่งเป็นรหัสหนึ่งบรรทัดแทนที่จะเป็นสองบรรทัดคั่นด้วยเครื่องหมายอัฒภาค

function(x)x[order(colSums(sapply(x,function(y)as.double(intToBits(y)))),decreasing=T)]

ผลรวมวิธีแทนที่จะเพิ่มคอลัมน์ด้วยcolSumsของเมทริกซ์ไบนารีที่สร้างโดยsapplyฉันเพิ่มองค์ประกอบในคอลัมน์ก่อนsapply"เสร็จสิ้น"

function(x)x[order(sapply(x,function(y)sum(as.double(intToBits(y)))),decreasing=T)]

การลดลงของ Revฉันต้องการลดระยะทางให้สั้นลง แต่ R squawks ที่ฉันถ้าฉันพยายามdecreasingทำให้orderฟังก์ชันสั้นลงซึ่งจำเป็นต้องได้รับคำสั่งที่ต้องการเป็นorderค่าเริ่มต้นที่เพิ่มขึ้นจากนั้นฉันจำได้ว่าrevฟังก์ชันเพื่อย้อนกลับเวกเตอร์ EUREKA !!! การเปลี่ยนแปลงล่าสุดในการแก้ปัญหาสุดท้ายคือfunctionเพื่อpryr::fที่จะประหยัดมากขึ้น 2 ไบต์

function(x)rev(x[order(sapply(x,function(y)sum(as.double(intToBits(y)))))])


1
ปรับปรุง51 bytesบนสนามกอล์ฟที่ยอดเยี่ยมของ @J.Doe!
Giuseppe

2

Haskell, 123C

import Data.List
import Data.Ord
b 0=[]
b n=mod n 2:b(div n 2)
c n=(n,(sum.b)n)
q x=map fst$sortBy(comparing snd)(map c x)

นี่เป็นวิธีแรกที่ฉันคิดว่าจะแก้ปัญหานี้ แต่ฉันคิดว่ามันมีวิธีที่ดีกว่าที่จะทำ นอกจากนี้หากใครรู้วิธีนำเข้า Haskell กอล์ฟฉันจะสนใจที่จะได้ยินมัน

ตัวอย่าง

*Main> q [4,2,15,5,3]
[4,2,5,3,15]
*Main> q [7,0,2]
[0,2,7]

รุ่น Ungolfed (พร้อมคำอธิบาย)

import Data.List
import Data.Ord

-- Converts an integer into a list of its bits
binary 0 = []
binary n = mod n 2 : binary (div n 2)

-- Creates a tuple where the first element is the number and the second element
-- is the sum of its bits.
createTuple n = (n, (sum.binary) n)

-- 1) Turns the list x into tuples
-- 2) Sorts the list of tuples by its second element (bit sum)
-- 3) Pulls the original number out of each tuple
question x = map fst $ sortBy (comparing snd) (map createTuple x)

มันจะเป็นประโยชน์ในการใช้สัญกรณ์มัดสำหรับmod, n`mod`2? มันมีความสำคัญเช่นเดียวกับการคูณและการหาร
John Dvorak

นั่นจะไม่เป็นประโยชน์สำหรับเหตุผลในการตีกอล์ฟเท่าที่ฉันเห็น ฉันจะเสียช่องว่างสองช่อง แต่ได้ backticks สองอันใช่ไหม
danmcardle

นำเข้า Data.List; import Data.Ord; import Data.Bits; q = sortBy (เปรียบเทียบ popCount) - 80C - หรือใช้วิธีการของคุณนำเข้า Data.List; import Data.Ord; b 0 = 0; bn = (mod n 2) + b (div n 2); q = sortBy (เปรียบเทียบ b) - 86C
bazzargh

ฉันพยายามหลีกเลี่ยงการนำเข้าโดยสิ้นเชิงสิ่งที่ดีที่สุดที่ฉันสามารถทำได้คือ 87C โดยการเล่นกอล์ฟ quicksort: b 0 = 0; bn = mod n 2 + b (div n 2); q [] = []; q (a: c) = f ( (ba>). b) c ++ a: f ((ba <=). b) c; f = (q.). ตัวกรอง
bazzargh

2

CoffeeScript (94)

รหัสที่อ่านได้ (212):

sort_by_ones_count = (numbers) ->
  numbers.sort (a, b) ->
    a1 = a.toString(2).match(/1/g).length
    b1 = b.toString(2).match(/1/g).length
    if a1 == b1
      0
    else if a1 > b1
      1
    else
      -1

console.log sort_by_ones_count [825, 3944, 11746, 15342, 15752, 16375, 19944, 21826, 28436, 28943, 32425]

ปรับให้เหมาะสม (213):

count_ones = (number) -> number.toString(2).match(/1/g).length
sort_by_ones_count = (numbers) -> numbers.sort (a, b) ->
  a1 = count_ones(a)
  b1 = count_ones(b)
  if a1 == b1 then 0 else if a1 > b1 then 1 else -1

น่าเบื่อ (147):

c = (n) -> n.toString(2).match(/1/g).length
s = (n) -> n.sort (a, b) ->
  a1 = c(a)
  b1 = c(b)
  if a1 == b1 then 0 else if a1 > b1 then 1 else -1

ผู้ประกอบการที่สามมีความยาวมากเกินไป (129):

c = (n) -> n.toString(2).match(/1/g).length
s = (n) -> n.sort (a, b) ->
  a1 = c(a)
  b1 = c(b)
  (0+(a1!=b1))*(-1)**(0+(a1>=b1))

นานเกินไปหยุดการร่าย (121):

c = (n) -> n.toString(2).match(/1/g).length
s = (n) -> n.sort (a, b) ->
  a1 = c(a)
  b1 = c(b)
  (-1)**(a1>=b1)*(a1!=b1)

รอบชิงชนะเลิศ (94):

c=(n)->n.toString(2).match(/1/g).length
s=(n)->n.sort((a, b)->(-1)**(c(a)>=c(b))*(c(a)!=c(b)))

2

Smalltalk (Smalltalk / X), 36 (หรืออาจ 24)

ใส่ใน; จัดเรียงแบบทำลายล้างใน:

a sort:[:a :b|a bitCount>b bitCount]

รุ่นที่ใช้งานได้: คืนอาร์เรย์ที่เรียงลำดับใหม่:

a sorted:[:a :b|a bitCount>b bitCount]

แม้จะมีตัวแปรที่สั้นกว่า (ผ่านชื่อหรือฟังก์ชันเป็นอาร์กิวเมนต์) ใน 24 ตัวอักษร แต่ (ถอนหายใจ) มันจะเรียงลำดับสูงสุดล่าสุด ดังที่ฉันเข้าใจแล้วสิ่งนี้ไม่ถูกขอดังนั้นฉันจึงไม่ถือว่าคะแนนกอล์ฟ:

a sortBySelector:#bitCount

2

PHP 5.4+ 131

ฉันไม่รู้ด้วยซ้ำว่าทำไมฉันถึงรบกวน PHP ในกรณีนี้:

<?unset($argv[0]);usort($argv,function($a,$b){return strcmp(strtr(decbin($b),[0=>'']),strtr(decbin($a),[0=>'']));});print_r($argv);

การใช้งาน:

> php -f sortbybinaryones.php 15342 28943 16375 3944 11746 825 32425 28436 21826 15752 19944
Array
(
    [0] => 16375
    [1] => 15342
    [2] => 32425
    [3] => 28436
    [4] => 19944
    [5] => 11746
    [6] => 28943
    [7] => 3944
    [8] => 15752
    [9] => 825
    [10] => 21826
)

ดีคนที่มีจะรำคาญกับ PHP
Einacio


2

DFSORT (ผลิตภัณฑ์การเรียงลำดับเมนเฟรมของ IBM) 288 (แต่ละบรรทัดซอร์สคือ 72 อักขระต้องมีที่ว่างในตำแหน่งที่หนึ่ง)

 INREC IFTHEN=(WHEN=INIT,BUILD=(1,2,1,2,TRAN=BIT)), 
       IFTHEN=(WHEN=INIT,FINDREP=(STARTPOS=3,INOUT=(C'0',C'')))
 SORT FIELDS=(3,16,CH,D) 
 OUTREC BUILD=(1,2)

เพื่อความสนุกและไม่มีคณิตศาสตร์

ใช้ไฟล์ (สามารถเรียกใช้งานจากโปรแกรมที่ใช้ "อาร์เรย์") กับจำนวนเต็ม ก่อนการเรียงลำดับจะแปลจำนวนเต็มเป็นบิต (ในฟิลด์ 16 อักขระ) จากนั้นเปลี่ยน 0s ในบิตเป็นไม่มีอะไร เรียงลำดับจากมากไปน้อยในผลลัพธ์ของบิตที่เปลี่ยนแปลง สร้างไฟล์ที่เรียงลำดับมีเพียงจำนวนเต็ม


2

C

void main()
{
 int a[]={7,6,15,16};
 int b,i,n=0;
 for(i=0;i<4;i++)
 {  for(b=0,n=0;b<=sizeof(int);b++)
      (a[i]&(1<<b))?n++:n;   
    a[i]=n;
 }
 for (i = 1; i < 4; i++) 
  {   int tmp = a[i];
      for (n = i; n >= 1 && tmp < a[n-1]; n--)
         a[n] = a[n-1];
      a[n] = tmp;
  }    
}

4
เนื่องจากนี่เป็นการแข่งขันกอล์ฟรหัสคุณควรลองย่อรหัสของคุณให้สั้นลง
Timtech

2

C #, 88 89

int[] b(int[] a){return a.OrderBy(i=>-Convert.ToString(i,2).Count(c=>c=='1')).ToArray();}

แก้ไข: ลำดับจากมากไปน้อยเพิ่มอักขระ


2

Javascript 84

แรงบันดาลใจจากคำตอบจาวาสคริปต์อื่น ๆ แต่ไม่มี eval และ regex

var r=(x)=>(+x).toString(2).split('').reduce((p,c)=>p+ +c)
[28943,825,11746,16375,32425,19944,21826,15752,15342,3944,28436].sort((x,y)=>r(x)-r(y));

คำถามคือรหัสกอล์ฟกรุณาลอง 'golf' รหัสของคุณ: ลบช่องว่างที่ไม่จำเป็นและพยายามทำให้รหัสของคุณมีขนาดเล็กที่สุด รวมถึงการนับจำนวนตัวอักษรในคำตอบของคุณ
ProgramFOX


2

Postscript, 126

เนื่องจากรายการค่าที่เราเรียงลำดับเป็นที่รู้จักกันก่อนหน้านี้และมีข้อ จำกัด มาก (32) งานนี้สามารถทำได้ง่ายแม้ว่าจะไม่มีการจัดเรียงในตัวโดยการเลือกค่าที่ตรงกันสำหรับ 1..32 (มันเป็น O (32n) หรือไม่อาจเป็นไปได้)

ขั้นตอนคาดว่าอาร์เรย์บนสแต็กและส่งกลับอาร์เรย์ 'เรียง'

/sort_by_bit_count {
    [ exch
    32 -1 1 {
        1 index
        {
            dup 2 32 string cvrs
            0 exch
            {48 sub add} forall
            2 index eq 
            {3 1 roll} {pop} ifelse
        } forall
        pop
    } for
    pop ]
} def

หรือปล้นพื้นที่สีขาวและอ่านง่าย:

/s{[exch 32 -1 1{1 index{dup 2 32 string cvrs 0 exch{48 sub add}forall 2 index eq{3 1 roll}{pop}ifelse}forall pop}for pop]}def

จากนั้นหากบันทึกลงในbits.psไฟล์สามารถใช้ดังนี้:

gs -q -dBATCH bits.ps -c '[(%stdin)(r)file 1000 string readline pop cvx exec] s =='
825 3944 11746 15342 15752 16375 19944 21826 28436 28943 32425
[16375 15342 32425 11746 19944 28436 28943 3944 15752 825 21826]

ฉันคิดว่ามันมีประสิทธิภาพเหมือนกับ Perl นี้ (ยังไม่มี Perl ที่นี่ด้วย):

sub f{map{$i=$_;grep{$i==(()=(sprintf'%b',$_)=~/1/g)}@_}reverse 1..32}

แม้ว่าที่แตกต่างจาก Postscript สามารถแข็งแรงเล่นกอล์ฟได้อย่างง่ายดาย:

sub f{sort{j($b)-j($a)}@_}sub j{$_=sprintf'%b',@_;()=/1/g}

Postscript! รักครั้งแรกของฉันภาษาโปรดของฉันตลอดเวลา! มันเป็นเรื่องดีที่ได้เห็นผู้เชื่อในภาษาโปรแกรมหนึ่งเดียว
AJMansfield

2

C - 124 111

นำไปใช้เป็นวิธีการและใช้ไลบรารีมาตรฐานสำหรับการเรียงลำดับ ตัวชี้ไปยังอาร์เรย์และขนาดควรถูกส่งผ่านเป็นพารามิเตอร์ สิ่งนี้จะทำงานกับระบบที่มีตัวชี้ 32- บิตเท่านั้น บนระบบ 64 บิตต้องใช้อักขระบางตัวเพื่อระบุนิยามของตัวชี้

เยื้องสำหรับการอ่าน

c(int*a,int*b){
    int d,e,i;
    for(d=e=i=0;i-32;){
        d+=*a>>i&1;e+=*b>>i++&1;
    }
    return d>e?-1:d<e;
}
o(r,s){qsort(r,s,4,c);}

ตัวอย่างการโทร:

main() {
    static int a[] ={1, 2, 3, 4, 5, 6, 7, 8, 9};
    o(a, 9);
}

2

Java 8: 144

static void main(String[]a){System.out.print(Stream.of(a).mapToInt(Integer::decode).sorted(Comparable.comparing(Integer::bitCount)).toArray());}

ในรูปแบบขยาย:

static void main(String[] args){
    System.out.print(
        Stream.of(args).mapToInt(Integer::decode)
              .sorted(Comparable.comparing(Integer::bitCount))
              .toArray()
        );
}

อย่างที่คุณเห็นการทำงานนี้โดยการแปลงargsa Stream<String>จากนั้นแปลง a Stream<Integer>ด้วยการInteger::decodeอ้างอิงฟังก์ชัน (สั้นกว่าparseIntหรือvalueOf) แล้วเรียงลำดับตามInteger::bitCountจากนั้นวางลงในอาร์เรย์แล้วพิมพ์ออกมา

สตรีมทำให้ทุกอย่างง่ายขึ้น

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