ตัวอักษรของลูกสาวฉัน


65

วันก่อนเรากำลังเขียนประโยคกับลูกสาวของฉันพร้อมจดหมายแม่เหล็กตู้เย็น ในขณะที่เราสามารถทำบางอย่าง ( I love cat) เราไม่มีตัวอักษรมากพอที่จะทำให้คนอื่น ( I love you too) เนื่องจากจำนวนตัวอักษรไม่เพียงพอo(4)

จากนั้นฉันก็พบว่าในขณะที่ชุดหนึ่งมี 3 eตัวอักษรมันมีเพียง 2 oตัว อาจได้รับแรงบันดาลใจจากhttp://en.wikipedia.org/wiki/Letter_frequencyสิ่งนี้จะไม่สะท้อนสถานการณ์จริง "บนตู้เย็น"

ปัญหา

กำหนดไฟล์ข้อความที่แต่ละบรรทัดมี "ประโยคตัวอย่าง" หนึ่งต้องการเขียนบนตู้เย็นเสนอชุดตัวอักษรที่มีจำนวนตัวอักษรขั้นต่ำ แต่ก็เพียงพอที่จะเขียนแต่ละประโยค

หมายเหตุ: ไม่สนใจเคสตัวอักษรแม่เหล็กทั้งหมดเป็นตัวพิมพ์ใหญ่อยู่แล้ว

อินพุต

ไฟล์มีประโยคที่คั่นด้วยการขึ้นบรรทัดใหม่:

hello
i love cat
i love dog
i love mommy
mommy loves daddy

เอาท์พุต

จัดเตรียมรายการเรียงตัวอักษรด้านหลังโดยที่แต่ละตัวอักษรปรากฏหลายครั้งเพียงพอที่จะเขียนประโยคใด ๆ :

acdddeghillmmmoostvyy

(ขอบคุณ isaacg!)

ผู้ชนะ

การใช้งานที่สั้นที่สุด (รหัส)

ปรับปรุง: การทดสอบ

ฉันได้สร้างแบบทดสอบเพิ่มเติมและลองตอบคำถามต่าง ๆ ที่นี่:

https://gist.github.com/romaninsh/11159751


2
ควรจะมีตัวอักษรvในการส่งออก;)
อันโตนิโอ Ragagnin

40
พวกเราจะได้รับอนุญาต / จำเป็นต้องทดแทนคว่ำลงMหาWหรือด้านข้างNสำหรับZ? ;-)
Ilmari Karonen

4
โดยทั่วไปคุณสามารถสร้างจดหมายใด ๆ โดยใช้Is
swish

7
อย่างจริงจังยิ่งขึ้นเมื่อคุณพูดว่า "ละเว้นกรณี" คุณหมายถึงว่าเราสามารถสมมติว่าอินพุตมีอยู่แล้วในกรณีเดียวกันหรือว่าเราต้องแปลงเป็นกรณีเดียวกันทั้งหมดหรือไม่ นอกจากนี้มันตกลงสำหรับเอาท์พุทที่จะรวมช่องว่างนำบางส่วน?
Ilmari Karonen

3
@Doorknob:_\¯
Ilmari Karonen

คำตอบ:


18

GolfScript, 28/34 ตัวอักษร

n/:a{|}*{a{.[2$]--}%*$-1=}%$

โปรแกรม 28 ตัวอักษรด้านบนถือว่าตัวอักษรอินพุตทั้งหมดอยู่ในกรณีเดียวกัน หากไม่จำเป็นต้องเป็นเช่นนั้นเราสามารถบังคับให้พวกมันเป็นตัวพิมพ์ใหญ่โดย{95&}%การใส่รหัสลงไปทั้งหมด 34 ตัวอักษร:

{95&}%n/:a{|}*{a{.[2$]--}%*$-1=}%$

หมายเหตุ:

  • สำหรับการดำเนินการที่ถูกต้องอินพุตต้องมีบรรทัดใหม่อย่างน้อยหนึ่งบรรทัด สิ่งนี้จะเป็นจริงสำหรับไฟล์ข้อความปกติที่มีการขึ้นบรรทัดใหม่ในตอนท้ายของแต่ละบรรทัด แต่อาจไม่เป็นจริงหากอินพุตประกอบด้วยเพียงหนึ่งบรรทัดที่ไม่มีบรรทัดใหม่ต่อท้าย สิ่งนี้สามารถแก้ไขได้ที่ค่าใช้จ่ายของสองตัวอักษรพิเศษโดยn+เตรียมรหัส

  • ตัวพิมพ์ใหญ่ที่ใช้ในเวอร์ชัน 34 ตัวอักษรนั้นหยาบจริงๆ - มันแมปตัวอักษร ASCII ตัวพิมพ์เล็กกับตัวพิมพ์ใหญ่ของพวกเขา (และช่องว่างกับNULs) แต่ทำให้ยุ่งเหยิงของตัวเลขและเครื่องหมายวรรคตอนส่วนใหญ่ ฉันสมมติว่าอินพุตจะไม่รวมอักขระดังกล่าว

  • เวอร์ชัน 28 อักขระปฏิบัติต่ออักขระอินพุตทั้งหมด (ยกเว้นบรรทัดใหม่และNULs) เท่า ๆ กัน โดยเฉพาะอย่างยิ่งหากอินพุตมีช่องว่างใด ๆ บางส่วนจะปรากฏในเอาต์พุตเช่นกัน พวกเขาจะจัดเรียงก่อนอักขระ ASCII ที่พิมพ์ได้อื่น ๆ อย่างไรก็ตามเวอร์ชั่น 34 ตัวอักษรนั้นไม่สนใจช่องว่าง (เพราะปรากฎว่าฉันสามารถทำได้โดยไม่ต้องคิดค่าใช้จ่ายเพิ่มเติมใด ๆ )

คำอธิบาย:

  • {95&}%คำนำหน้าเพิ่มเติมเป็นตัวเลือกเพิ่มการป้อนข้อมูลโดย zeroing out บิตที่หกของรหัส ASCII ของแต่ละไบต์อินพุต ( ) แมปนี้ตัวอักษร ASCII ตัวพิมพ์เล็กเป็นตัวพิมพ์ใหญ่เว้นวรรคเป็น null ไบต์และทำให้บรรทัดใหม่ไม่เปลี่ยนแปลง95 = 64 + 31 = 10111112

  • n/แยกการป้อนข้อมูลในการขึ้นบรรทัดใหม่และกำหนดอาร์เรย์ที่เกิดขึ้นลงในตัวแปร:a aจากนั้น{|}*คำนวณชุดยูเนี่ยนของสตริงในอาร์เรย์ซึ่ง (สมมติว่าอาร์เรย์มีองค์ประกอบอย่างน้อยสององค์ประกอบ) ให้สตริงที่มีอักขระที่ไม่ซ้ำกัน (ไม่ใช่บรรทัดใหม่) ทั้งหมดในอินพุต

  • { }%วนซ้ำต่อไปนี้จะวนซ้ำอักขระแต่ละตัวเหล่านี้ ภายในเนื้อความลูปการวนa{.[2$]--}%ซ้ำภายในวนซ้ำสตริงในอาร์เรย์aโดยลบอักขระทุกตัวที่ไม่เท่ากับเท่ากับลูปรอบนอกออกจากแต่ละสตริง

    วนรอบด้านในปล่อยโค้ด ASCII ของอักขระปัจจุบันลงบนสแต็กด้านล่างอาร์เรย์ที่กรอง เราใช้สิ่งนี้โดยการทำซ้ำอาร์เรย์ที่กรองแล้วซ้ำหลาย ๆ ครั้งตามที่ระบุโดยรหัส ASCII ( *) ก่อนที่จะทำการจัดเรียง ( $) และรับองค์ประกอบสุดท้าย ( -1=) ซึ่งจะให้สตริงที่ยาวที่สุดในอาเรย์ที่ถูกกรอง (เนื่องจากทั้งหมดประกอบด้วยการซ้ำของอักขระเดียวกันการเรียงลำดับพจนานุกรมเพียงเรียงลำดับตามความยาว) ยกเว้นว่าอักขระมีรหัส ASCII เป็นศูนย์ซึ่งในกรณีนี้จะไม่มีผลใด ๆ

  • ในที่สุด$ตอนท้ายก็แค่เรียงลำดับผลลัพธ์ตามตัวอักษร


3
น่าอัศจรรย์ สิ่งที่ต้องทำ: เรียนรู้ GolfScript!
DLosc

1
คุณยังอาจลดไป n/:a{|}*{{{=}+,}+a%$-1=}%$26:
Howard

13

J - 37 ตัวอักษร

อ่านจาก stdin, ส่งออกไปยังคอนโซล

dlb#&a.>./+/"2=/&a.tolower;._2[1!:1]3

1!:1]3คือการเรียกไปยัง stdin tolower;._2ดำเนินการสองหน้าที่โดยแยกบรรทัดและทำให้เป็นตัวพิมพ์เล็กพร้อมกัน แล้วเรานับจำนวนครั้งที่ตัวละครที่เกิดขึ้นในแต่ละแถวมี+/"2=/&a.และใช้เวลาไม่เกิน pointwise >./เหนือเส้นทั้งหมดที่มี

#&a.สุดท้ายเราดึงที่มากของตัวละครแต่ละตัวออกมาจากตัวอักษรที่มี ซึ่งรวมถึงช่องว่างทั้งหมดที่พบที่ด้านหน้าเนื่องจาก ASCII dlbต่ำมูลค่าเพื่อให้เราเพียงแค่ลบช่องว่างชั้นนำของพวกเขาด้วย


12

JavaScript (ECMAScript 6) - 148 139 135 ตัวอักษร

รุ่น 2:

อัปเดตเพื่อใช้ความเข้าใจอาร์เรย์:

[a[i][0]for(i in a=[].concat(...s.split('\n').map(x=>x.split(/ */).sort().map((x,i,a)=>x+(a[i-1]==x?++j:j=0)))).sort())if(a[i-1]<a[i])]

รุ่น 1:

[].concat(...s.split('\n').map(x=>x.split(/ */).sort().map((x,i,a)=>x+(a[i-1]==x?++j:j=0)))).sort().filter((x,i,a)=>a[i-1]!=x).map(x=>x[0])

สมมติว่า:

  • สายป้อนที่อยู่ในตัวแปรs;
  • เราสามารถละเว้นกรณีของอินพุต (ตามที่ระบุโดยคำถาม - นั่นคือทั้งหมดในกรณีบนหรือล่าง);
  • เอาท์พุทเป็นอาร์เรย์ของตัวละคร (ซึ่งเป็นเรื่องที่ใกล้เคียงที่สุดเท่าที่ JavaScript สามารถได้รับความต้องการของ OP ของรายการของตัวละคร); และ
  • เอาต์พุตจะถูกแสดงบนคอนโซล

ด้วยความคิดเห็น:

var l = s.split('\n')             // split the input up into sentences
         .map(x=>x.split(/ */)   // split each sentence up into letters ignoring any
                                  // whitespace
                  .sort()         // sort the letters in each sentence alphabetically
                  .map((x,i,a)=>x+(a[i-1]==x?++j:j=0)))
                                  // append the frequency of previously occurring identical
                                  // letters in the same sentence to each letter.
                                  // I.e. "HELLO WORLD" =>
                                  // ["D0","E0","H0","L0","L1","L2","O0","O1","R0","W0"]
[].concat(...l)                   // Flatten the array of arrays of letters+frequencies
                                  // into a single array.
  .sort()                         // Sort all the letters and appended frequencies
                                  // alphabetically.
  .filter((x,i,a)=>a[i-1]!=x)     // Remove duplicates and return the sorted
  .map(x=>x[0])                   // Get the first letter of each entry (removing the
                                  // frequencies) and return the array.

ถ้าคุณต้องการ:

  • ส่งคืนเป็นสตริงแล้วเพิ่ม.join('')ที่ส่วนท้าย
  • รับอินพุตจากผู้ใช้จากนั้นแทนที่sตัวแปรด้วยprompt(); หรือ
  • เขียนเป็นฟังก์ชั่นfแล้วเพิ่มf=s=>ไปยังจุดเริ่มต้น

วิ่ง:

s="HELLO\nI LOVE CAT\nI LOVE DOG\nI LOVE MOMMY\nMOMMY LOVE DADDY";
[].concat(...s.split('\n').map(x=>x.split(/ */).sort().map((x,i,a)=>x+(a[i-1]==x?++j:j=0)))).sort().filter((x,i,a)=>a[i-1]!=x).map(x=>x[0])

ให้ผลลัพธ์:

["A","C","D","D","D","E","G","H","I","L","L","M","M","M","O","O","T","V","Y","Y"]

1
ดี! คุณสามารถบันทึก 3 ไบต์โดยการลด/\s*/การ/ */และลบ parens รอบj=0
nderscore

1
คุณไม่สามารถใช้...แทนapply?
Ven

ขอขอบคุณคุณทั้งสอง - ที่ช่วยประหยัด 9 ตัวอักษร - ตัวดำเนินการspread ( ...) เป็นสิ่งที่ฉันไม่เคยเจอมาก่อน
MT0

[].concat(...s.split`N`.map(x=>x.split(/ */).map((x,i,a)=>x+(a[x]=a[x]?++j:j=1)))).sort().map((x,i,a)=>a[i-1]<x?x[0]:'').join``;
l4m2

11

Perl - 46 ไบต์

#!perl -p
$s=~s/$_//ifor/./g;$s.=uc}for(sort$s=~/\w/g){

นับ Shebang เป็น 1 นี่เป็นคำแปลอย่างย่อของโซลูชัน Ruby ด้านล่าง


Ruby 1.8 - 72 ไบต์

s='';s+=$_.upcase.scan(/./){s.sub!$&,''}while gets;$><<s.scan(/\w/).sort

stdinการป้อนข้อมูลที่นำมาจาก

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

$ more in.dat
Hello
I love cat
I love dog
I love mommy
Mommy loves daddy

$ ruby fridge-letters.rb < in.dat
ACDDDEGHILLMMMOOSTVYY

ต้องเรียงลำดับผลลัพธ์
Matt

@ แก้ไขแล้วตอนนี้
primo

ดี หากคุณ Perl เป็นรางที่ผ่านมาแม้ว่าคุณจะต้องการพื้นที่ระหว่างและ/i for
tobyink

8

Python - 206 204 199 177 145 129 117 94 88 ตัวอักษร

print(''.join(c*max(l.lower().count(c)for l in open(f))for c in map(chr,range(97,123))))

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


8
ในจิตวิญญาณของยูนิกซ์ - คุณสามารถอ่านได้จาก stdin
romaninsh

5
ทำให้ชื่อไฟล์ยาวหนึ่งตัวเสมอ ...

3
@Tal ฉันยังใหม่ แต่ถ้ามันช่วยตัวละครทำไมไม่?

1
โดยสมมติว่าfชื่อไฟล์อินพุตและใช้ตัวพิมพ์ใหญ่ (ตัวอักษรแม่เหล็กทั้งหมดเป็นตัวพิมพ์ใหญ่ต่อไป) คุณสามารถรับมันได้ที่ 91:print(''.join([chr(i)*max(l.upper().count(chr(i))for l in open(f))for i in range(65,91)]))
Gabe

1
@ njzk2 ดีถ้าเราทำงานนี้ในคอนโซลในทางทฤษฎีมันจะเป็นเพียงแค่พิมพ์ผลด้วยตัวเอง ...
Tal

6

Ruby 1.9+, 51 (หรือ 58 หรือ 60)

a=*$<
?a.upto(?z){|c|$><<c*a.map{|l|l.count c}.max}

ถือว่าทุกอย่างเป็นตัวพิมพ์เล็ก กรณีค่าใช้จ่ายไม่รู้สึก 7 ตัวอักษรผ่านทาง.upcaseในขณะที่กรณีตายและเอาท์พุทพิมพ์เล็กค่าใช้จ่าย 9 .downcaseตัวอักษรผ่านทาง


4

R (156, รวมไฟล์ที่อ่าน)

ด้วยตารางฉันสร้างตารางความถี่จดหมายสำหรับแต่ละประโยค จากนั้นฉันก็ลงเอยด้วยการสละค่าสูงสุดสำหรับตัวอักษรแต่ละตัว

a=c();for(w in tolower(read.csv(fn,h=F)$V1))a=c(a,table(strsplit(w,"")[[1]]));a=tapply(seq(a),names(a),function(i)max(a[i]))[-1];cat(rep(names(a),a),sep="")

Ungolfed:

a=c()
words = read.csv(fn,h=F)$V1
for(w in tolower(words))
  a=c(a, table(strsplit(w, "")[[1]]))
a = tapply(seq(a), names(a), function(i) max(a[i]))[-1] ## The -1 excludes the space count.
cat(rep(names(a), a), sep="")

วิธีการแก้:

acdddeghillmmmoooooostuvyy

@lambruscoAcido คุณสามารถ vectorize สามบรรทัดแรก (ของโค้ด ungolfed) ซึ่งจะให้คุณa=unlist(lapply(readLines(fn),function(x)table(strsplit(tolower(x),""))));a=tapply(seq(a),names(a),function(i)max(a[i]))[-1];cat(rep(names(a),a),sep="")แต่สั้นลงเพียง 3 ตัวอักษรเท่านั้น
jkd

อีกวิธีหนึ่งที่มีเพียง 112 ตัวอักษรจะcat(unlist(sapply(letters,function(i)rep(i,max(sapply(gregexpr(i,readLines(f)),function(x)sum(x>0)))))),sep="")ถือว่าfเป็นชื่อไฟล์
jkd

4

Haskell, 109 108

import Data.List
import Data.Char
main=interact$sort.filter(/=' ').foldl1(\x y->x++(y\\x)).lines.map toLower

โปรแกรมอ่านจาก stdin และเขียนไปยัง sdtout

มันค่อนข้างตรงไปตรงมา: มันแบ่งสตริงลงในรายการของบรรทัดและสร้างใหม่โดยทำซ้ำในรายการและเพิ่มตัวอักษรใหม่ที่มีอยู่ในแต่ละบรรทัด


โอ้ทำไมฉันไม่เคยได้ยิน (\\) มาก่อนเลย
Flonk

@Flonk haskell.org/ghc/docs/7.6-latest/html/l ไลบรารี/base-4.6.0.1/…
lortabac

4

Perl 6: 56 53ตัวอักษร; 58 55ไบต์

say |sort
([∪] lines.map:{bag comb /\S/,.lc}).pick(*)

สำหรับแต่ละบรรทัดสิ่งนี้จะรวมเข้าด้วยกันสำหรับอักขระที่ไม่ใช่ช่องว่างของสตริงที่ต่ำกว่า ( comb /\S/,.lc) และสร้าง a Bagหรือคอลเล็กชันของอักขระแต่ละตัวและจำนวนครั้งที่เกิดขึ้น [∪]ใช้เวลาร่วมกันของBagทุกบรรทัดซึ่งได้รับจำนวนครั้งสูงสุดที่ตัวละครเกิดขึ้น .pick(*)มันคือแฮ็ค - y ที่นี่ แต่มันเป็นวิธีที่สั้นที่สุดในการดึงตัวละครทั้งหมดออกมาจากBagจำนวนครั้งที่มันเกิดขึ้น

แก้ไข: เพื่อดูว่ามันจะสั้นกว่านี้หรือไม่ฉันลองแปลคำตอบทับทิมของฮิสโตแคต มันเป็นตัวละคร 63 ตัว แต่ฉันก็ยังชอบแนวทางนี้อยู่

$!=lines».lc;->$c{print $c x max $!.map:{+m:g/$c/}} for"a".."z"

3

Haskell, 183 162 159

สมมติว่าไฟล์อยู่ในfile.txt!

import Data.Char
import Data.List
main=readFile"file.txt">>=putStr.concat.tail.map(tail.maximum).transpose.map(group.sort.(++' ':['a'..'z'])).lines.map toLower

หาก file.txt มีตัวอย่างเช่น

abcde
abcdef
aaf

สคริปต์จะส่งออก

aabcdef

โดยพื้นฐานแล้วฉันจะต่อท้ายตัวอักษรทั้งหมดในแต่ละบรรทัดดังนั้นเมื่อจัดกลุ่มและเรียงลำดับฉันแน่ใจว่าฉันจะจบลงด้วยรายการที่มี 27 องค์ประกอบ ต่อไปผมจะไขว้ "ตารางความถี่" ["a","","aaa","aa","aaaa"]เพื่อให้แต่ละแถวในอาร์เรย์นี้ประกอบด้วยความถี่ของตัวอักษรเดียวในแต่ละบรรทัดเช่น จากนั้นฉันเลือกจำนวนสูงสุดของแต่ละอาร์เรย์ (ซึ่งทำงานเหมือนที่ฉันต้องการเนื่องจากการOrdทำงานของ -instance of Strings) และวางจดหมายที่ฉันต่อท้ายเมื่อเริ่มต้นกำจัดช่องว่างและออกผลลัพธ์


1
แทนที่จะdrop 1ใช้เพียงtail
Bergi

@Bergi ฮ่าฮ่า derp ขอบคุณ! ฉันเปลี่ยนมันในโพสต์
Flonk

3

C, 99 ตัวอักษร

t[256];main(c){for(--*t;++t[1+tolower(getchar())];);for(c=97;c<123;c++)while(t[c]--)putchar(c-1);}

มันขัดข้องถ้ามีการขึ้นบรรทัดใหม่ให้น้อยกว่าหนึ่งรายการ ฉันคิดว่ามันคงง่ายมาก


ฉันพยายาม แต่มันก็ไม่ได้ผลลัพธ์ที่ถูกต้อง gist.github.com/romaninsh/11159751
romaninsh

3

kdb (q / k): 59 ตัวอักษร:

d:.Q.a! 26#0
.z.pi:{d|:.Q.a##:'=_y}.z.exit:{-1@,/.:[d]#'!:d}
  • สร้างพจนานุกรมเมล็ดที่เรียงลำดับล่วงหน้าจากตัวอักษร. Qa
  • ประมวลผลอินพุตแต่ละบรรทัด, แปลงเป็นตัวพิมพ์เล็ก, จัดกลุ่มเป็นพจนานุกรม, นับแต่ละองค์ประกอบ, ใช้ตัวอักษรจากผลลัพธ์ (เช่นช่องว่างพรุน, การขึ้นบรรทัดใหม่, ฯลฯ ในขั้นตอนนี้) และใช้ max-assign to global d เพื่อรักษาผลรวมทั้งหมด
  • กำหนดตัวจัดการทางออกซึ่งได้รับการส่งผ่านไปยัง. z.pi เพื่อบันทึกตัวคั่น แต่ไม่ได้ใช้ที่นั่น รับจากคีย์ - ค่าแต่ละรายการเพื่อสร้างรายการของตัวอักษรแผ่และพิมพ์เป็น stdout ในที่สุด

-1 เพิ่มบรรทัดใหม่โดยใช้ 1 จะบันทึกอักขระ แต่ไม่สร้างเอาต์พุตที่ระบุ หวังว่าฉันจะกำจัด. z.pi / .z.exit สำเร็จรูปซึ่งจะลบ 14 ตัวอักษร

แก้ไข: หลีกเลี่ยงการใช้ inter / asc โดยใช้พจนานุกรมเมล็ด


3

Perl, 46

for$:(a..z){$a[ord$:]|=$:x s/$://gi}}{print@a

ต่อไปนี้เป็นโซลูชัน Perl อื่นอ่านจาก STDIN ต้องการ-nสวิตช์ (+1 เพื่อนับ) เชื่อมโยงกับคะแนนของพรีโม่ แต่ทำงานโดยไม่มีข้อร้องเรียน :-) มันใช้ประโยชน์จากข้อเท็จจริงที่ว่าorผลลัพธ์ของbitwise มีความยาวของอาร์กิวเมนต์สตริงที่ยาวกว่า


1
ลองกับการทดสอบของฉันและใช้งานได้ดี
romaninsh

3

ฉันกำลังเพิ่มโซลูชันของตัวเอง:

Bash - 72

สมมติว่าอินพุตอยู่ในไฟล์ "i"

for x in {A..Z};do echo -n `cat i|sed "s/[^$x]//g"|sort -r|head -1`;done

คำอธิบาย

สำหรับจดหมายแต่ละฉบับที่เป็นไปได้ให้กรองออกจากไฟล์อินพุตเท่านั้นทำให้มีลักษณะดังนี้:

AAA
A
A

AAAA

A
AAAAAAAAAAAAAAAA

จากนั้นจะจัดเรียงผลลัพธ์และเลือกบรรทัดที่ยาวที่สุด echo -nมีการลบบรรทัดใหม่


3

ทุบตี, 171 159 158, 138 พร้อมเอาต์พุตขยะ

ต้องใช้ตัวพิมพ์เล็กเท่านั้น ถือว่าไฟล์นั้นมีชื่อว่า_(ขีดล่าง) สูงสุด 26 บรรทัดในไฟล์อินพุตเนื่องจากชื่อไฟล์น่ารำคาญที่splitสร้างขึ้น (xaa, xab ... xaz, ???)

ในbash, เอาท์พุท{a..z}a b c d e f ...

touch {a..z}
split _ -1
for l in {a..z}
do for s in {a..z}
do grep -so $l xa$s>b$l
if [ `wc -l<b$l` -ge `wc -l<$l` ]
then mv b$l $l
fi
done
tr -d '\n'<$l
done

ตัวอย่างผลลัพธ์

acdddeghillmmmoostvyy

คำอธิบาย

touch {a..z}

สร้างไฟล์ที่เราจะอ่านในภายหลังเพื่อที่ bash จะไม่บ่นว่าไม่มีอยู่ หากคุณลบบรรทัดนี้คุณจะบันทึก 13 ตัวอักษร แต่ได้รับเอาต์พุตขยะจำนวนมาก

split _ -1

แบ่งไฟล์อินพุตออกเป็นส่วน ๆ แต่ละการจัดเก็บ 1 บรรทัด ไฟล์ที่คำสั่งนี้สร้างขึ้นมีชื่อว่า xaa, xab, xac และอื่น ๆ ฉันไม่รู้ว่าทำไม

for l in {a..z}
do for s in {a..z}

สำหรับตัวอักษรแต่ละอ่านผ่านสายทั้งหมดเก็บไว้ในไฟล์$lxa$s

do grep -so $l xa$s>b$l

ลบ-sสวิตช์เพื่อบันทึก 1 อักขระและรับเอาต์พุตขยะจำนวนมาก มันป้องกันไม่ให้grepบ่นเกี่ยวกับไฟล์ที่ไม่มีอยู่ (จะเกิดขึ้นเว้นแต่คุณมี 26 บรรทัดอินพุต) นี้จะประมวลผลไฟล์xa$sเอาอะไร แต่ปรากฏของและส่งออกไปยังแฟ้ม$l b$lดังนั้น "ฉันรักแม่" จึงกลายเป็น "mmm" โดยมีบรรทัดใหม่ตามตัวอักษรแต่ละตัวเมื่อ$lเป็น m

if [ `wc -l<b$l` -ge `wc -l<$l` ]

หากจำนวนบรรทัดในไฟล์ที่เราเพิ่งสร้างมีค่ามากกว่าหรือเท่ากับ (เช่นตัวอักษรมากขึ้นเนื่องจากมีหนึ่งตัวอักษรต่อบรรทัด) จำนวนบรรทัดในผลลัพธ์สูงสุดของเราจนถึงขณะนี้ (เก็บไว้ใน$l) ...

then mv b$l $l

... $lเก็บบันทึกใหม่ของเราในแฟ้ม ในตอนท้ายของลูปนี้เมื่อเราผ่านทุกบรรทัดไฟล์$lจะเก็บเส้น x แต่ละเส้นที่มีตัวอักษร$lโดยที่ x คือจำนวนครั้งสูงสุดของตัวอักษรนั้นในหนึ่งบรรทัด

fi
done
tr -d '\n'<$l

เอาท์พุทเนื้อหาของไฟล์ของเราสำหรับตัวอักษรนั้นลบบรรทัดใหม่ หากคุณไม่ต้องการลบบรรทัดใหม่ให้เปลี่ยนบรรทัดด้วยtrเป็นecho $lประหยัด 6 ตัวอักษร

done

พยายามกับ GNU ทุบตี, รุ่น 3.2.51 (แอปเปิ้ล) แต่ไฟล์ '-l1aa' ในโฟลเดอร์ปัจจุบันที่มีการป้อนข้อมูล ..
romaninsh

@romaninsh อาจเป็นเพราะคุณมีเวอร์ชั่นที่แตกต่างจากsplit(จาก coreutils) ฉันกำลังใช้ GNU bash 4.3.8 และ GNU coreutils 8.21 บน Ubuntu 14.04 และใช้งานได้ดี (มันยังทำงานกับ Ubuntu 13.10 ก่อนที่ฉันจะอัพเกรด) แต่ผมไม่ต้องวางโปรแกรมและแฟ้มใส่ในไดเรกทอรีที่แยกต่างหากเพื่อให้การทำงานอย่างถูกต้อง - ฉันสงสัยว่านี่เป็นเพียงเพราะล้านของไฟล์ขยะที่อยู่ในโฟลเดอร์ที่บ้านของฉัน

@ananinsh ในความเป็นจริงถ้าคุณดูคำสั่งที่แน่นอนในสคริปต์: split _ -l1และคุณสังเกตเห็นว่าการป้อนข้อมูลของคุณจะถูกบันทึกไว้-l1aaฉันคิดว่ารุ่นของคุณsplit ไม่ได้รับการยอมรับ-l1เป็นตัวเลือกและแทนที่จะเป็นคำนำหน้าสำหรับการส่งออก . ลองวางช่องว่างระหว่าง-lและ1หรือวาง--lines=1หรือเพียงแค่-1(ดูเหมือนจะเป็นไวยากรณ์ล้าสมัยและมากขึ้นซึ่งตอนนี้ฉันจะอัปเดตโพสต์ด้วย)

3

C #, 172 ไบต์

var x="";foreach(var i in File.ReadAllText(t).ToLower().Split('\r','\n'))foreach(var j in i)if(x.Count(c=>c==j)<i.Count(c=>c==j))x+=j;string.Concat(x.OrderBy(o=>o)).Trim();

ฉลาด ... ฉลาด ... ฉันคิดเกี่ยวกับการเล่นกับ linq แต่สงสัยว่ามันจะสั้นเท่ากับ foreachs ที่ถูกบิดเหล่านี้ :)
Noctis

2

Python 2 - 129

แนวคิดจาก @Tal

a,r=[0]*26,range(26)
for l in open('f'):a=[max(a[i],l.lower().count(chr(i+97)))for i in r]
print''.join(chr(i+97)*a[i]for i in r)

อีกสองสามวิธีในการทำสิ่งเดียวกันในจำนวนอักขระที่เท่ากัน:

a=[0]*26
b='(chr(i+97)))for i in range(26)'
exec'for l in open("f"):a=[max(a[i],l.lower().count'+b+']\nprint"".join(a[i]*('+b+')'

a=[0]*26
b='(chr(i+97)))for i in range(26))'
exec'for l in open("f"):a=list(max(a[i],l.lower().count'+b+'\nprint"".join(a[i]*('+b

นี่ถือว่าไฟล์ถูกบันทึกเป็น f ในไดเรกทอรีที่เข้าถึงได้ โปรแกรมนี้สามารถรันได้โดยตรงโดยไม่จำเป็นต้องป้อนข้อมูลเพิ่มเติม


ทำไมถึงลงคะแนน? ขออภัยถ้าฉันทำอะไรผิด
isaacg

2

Mathematica v10 - 110

ยังไม่ออก แต่การอ่านเอกสารใหม่อย่างระมัดระวังฉันคิดว่านี่น่าจะใช้ได้:

StringJoin@MapIndexed[#2~Table~{#1}&,Rest@Merge[Counts/@Characters@StringSplit[ToLowerCase@Input[],"\n"],Max]]

2

สกาลา, 125 ตัวอักษร

val i=""::io.Source.stdin.getLines.toList.map(_.toLowerCase);println('a'to'z'map(c=>(""+c)*i.map(_.count(_==c)).max)mkString)

ก่อนอื่นฉันอ่านอินพุตแปลงเป็นตัวพิมพ์เล็กและเพิ่มหนึ่งบรรทัดว่าง

จากนั้นสำหรับตัวอักษรแต่ละตัวจากaถึงzฉันซ้ำตัวอักษรจำนวนสูงสุดที่ปรากฏในบรรทัดใด ๆ (นั่นเป็นเหตุผลที่ฉันต้องการบรรทัดว่าง:maxไม่สามารถเรียกใช้ในอินพุต enpty) จากนั้นฉันก็เข้าร่วมผลลัพธ์และพิมพ์ไปยังผลลัพธ์

หากต้องการอ่านจากไฟล์ให้แทนที่stdinด้วยการfromFile("FILENAME")เพิ่มขนาดของรหัสเป็น 132 อักขระ + ความยาวชื่อไฟล์


2

Javascript, 261 ตัวอักษร

eval('s=prompt().toUpperCase().split("\\n");Z=[########0,0];H=Z.slice();s@r){h=Z.slice();r.split("")@c){if(c.match(/\\w/))h[c.charCodeAt(0)-65]++});H=H@V,i){return V>h[i]?V:h[i]})});s="";H@n,i){s+=Array(n+1).join(String.fromCharCode(i+97))});s'.replace(/@/g,".map(function(").replace(/#/g,"0,0,0,"))

ลบeval(...)และดำเนินการเพื่อรับรหัสจริง; นี่คือ ( ค่อนข้างบีบอัด )

sมัลติฟังก์ชั่นเป็นอาร์เรย์ของบรรทัดและเป็นสตริงเอาท์พุทhประกอบด้วยฮิสโตแกรมของตัวอักษรต่อบรรทัดและHมีฮิสโตแกรมที่มีค่าสูงสุดจนถึงปัจจุบัน มันไม่คำนึงถึงขนาดตัวพิมพ์และไม่สนใจอะไรเลยนอกจาก az และ AZ (ฉันคิดว่า ... บางครั้งอาร์เรย์ของ JS จะแปลก ๆ )

ถูกต้องแล้ว :)


นี่เป็นเพียงการรวมตัวอักษรไม่ใช่คำถามที่ถาม ตัวอักษรควรจะรวมเป็นชุดขั้นต่ำเปลือยเพื่อสร้างประโยคเดียวใด ๆ ในการป้อนข้อมูลไม่ได้ทั้งหมดของพวกเขา ฉันชอบวิธีการของคุณเพื่อป้องกันไม่ให้ต้องเรียงลำดับผลลัพธ์
Matt

@ แมทใช่แล้ว ... ฉันจะแก้ไขในภายหลัง ยังไม่ได้มีเวลาจริงๆ
tomsmeding

1
สงสัยว่าเกิดอะไรขึ้นกับ@ฉันจนกระทั่งฉันถึงจุดจบ ผมชอบมัน :)
แมตต์

2

JavaScript ( ES5) ) 141 ไบต์

ตัวแปรสมมติว่าsเป็นสตริงอินพุตที่ไม่มีข้อกำหนดการตรวจสอบเคสและเอาต์พุตอาร์เรย์:

for(a in s=s[o=_='',y='split']('\n'))for(i=0;x=s[a][i++];)o+=x!=0&&(l=s[a][y](x).length-~-o[y](x).length)>0?Array(l).join(x):_;o[y](_).sort()

ฉันทดสอบโซลูชันของคุณและมองเข้าไปข้างใน "o" เพื่อหาผลลัพธ์ แต่ดูเหมือนจะไม่เรียงอย่างถูกต้อง (ดูgist.github.com/romaninsh/11159751 )
romaninsh

@romaninsh ผลลัพธ์ที่ฉันเห็นในส่วนสำคัญของคุณ
ดูถูก

ใช่นั่นคือการอ้างอิง / เอาท์พุทที่ถูกต้อง เมื่อฉันลองใช้รหัสของคุณฉันได้รับสิ่งนี้: gist.github.com/romaninsh/11161018
romaninsh

ขอโทษถ้าฉันทำตัวอย่างของคุณไม่ถูกต้อง
romaninsh

@romaninsh อ่าฉันตั้งใจจะให้มันทำงานในคอนโซลของเบราว์เซอร์ นี่คือเวอร์ชันที่จัดรูปแบบใหม่ซึ่งทำงานบนโหนด: gist.github.com/nderscore/96aa888c77d275c26c15
nderscore

2

PowerShell - 141

อ่านข้อความจากไฟล์ชื่อ 'a'

$x=@{}
gc a|%{[char[]]$_|group|%{$c=$_.name.tolower().trim()
$n=$_.count;$x[$c]=($n,$x[$c])[$n-lt$x[$c]]}}
($x.Keys|sort|%{$_*$x[$_]})-join""

2

Groovy, 113/127 102/116 ตัวอักษร

สมมติว่าไฟล์ทั้งหมดในหนึ่งกรณี (102 ตัวอักษร):

t=new File('f').text;t.findAll('[A-Z]').unique().sort().each{c->print c*t.readLines()*.count(c).max()}

สมมติว่าไฟล์เป็นกรณีผสม (116 ตัวอักษร):

t=new File('f').text.toUpperCase();t.findAll('[A-Z]').unique().sort().each{c->print c*t.readLines()*.count(c).max()}

โดยทั่วไป:

  • t=new File('f').text เพื่อรับข้อความของไฟล์
  • t.findAll('[A-Z]').unique().sort().each{c-> ในการรับอักขระที่ไม่ซ้ำกันให้เรียงลำดับและทำซ้ำ
  • print c*t.readLines()*.count(c).max() รับค่าสูงสุดที่ปรากฏในบรรทัดเดียวและพิมพ์อักขระที่หลายต่อหลายครั้ง

2

Bash (ส่วนใหญ่ awk) - 172 163 157

awk -v FS="" '{delete l;for(i=1;i<=NF;i++)l[toupper($i)]++;for(i in l)o[i]=(o[i]>l[i]?o[i]:l[i])}END{for(i in o)for(j=0;j<o[i];j++)print i}'|sort|tr -d ' \n'

ข้อความต้องถูกไพพ์ไปที่ awk (หรือระบุเป็นไฟล์)

ตัวอย่างการป้อนข้อมูล

Hello
I love cat
I love dog
I love mommy
Mommy loves daddy

ตัวอย่างผลลัพธ์

ACDDDEGHILLMMMOOSTVYY

PHP (อาจจะดีกว่า) - 174 210

$o=array();foreach(explode("\n",$s) as $a){$l=array();$i=0;while($i<strlen($a)){$k=ucfirst($a[$i++]);if($k==' ')continue;$o[$k]=max($o[$k],++$l[$k]);}}ksort($o);foreach($o as $k=>$v)for($i=0;$i<$v;$i++)echo $k;

สมมติว่าสตริงมีอยู่ในตัวแปร $ s

ตัวอย่างการป้อนข้อมูล

Hello
I love cat
I love dog
I love mommy
Mommy loves daddy

ตัวอย่างผลลัพธ์

ACDDDEGHILLMMMOOSTVYY

2

ฉันรู้ว่านี่อาจไม่ใช่คำตอบที่มีประสิทธิภาพที่สุด แต่ฉันต้องการลองและแก้ไขปัญหาต่อไป นี่คือรูปแบบ ObjC ของฉัน:

- (NSArray *) lettersNeededForString:(NSString *)sourceString {
    sourceString = [sourceString stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    sourceString = [sourceString stringByReplacingOccurrencesOfString:@" " withString:@""];
    const char * sourceChars = sourceString.UTF8String;
    NSMutableArray * arr = [NSMutableArray new];
    for (int i = 0; i < sourceString.length; i++) {
        [arr addObject:[NSString stringWithFormat:@"%c", sourceChars[i]]];
    }
    return [arr sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
}    

จากนั้นคุณสามารถเรียกมันว่าสตริงอะไรก็ได้:

NSArray * letters = [self lettersNeededForString:@"Hello\nI love cat\nI love dog\nI love mommy\nMommy loves daddy"];
NSLog(@"%@",letters);

ฉันกำลังคิดเกี่ยวกับแอปพลิเคชันที่มีข้อความจำนวนมากและฉันก็ไม่จำเป็นต้องนับชุดของฉัน สำหรับสิ่งนี้ฉันเพิ่มวิธีการรับ:

- (NSDictionary *) numberOfLettersNeededFromString:(NSString *)sourceString {

    sourceString = [sourceString stringByReplacingOccurrencesOfString:@"\n" withString:@""];
    sourceString = [sourceString stringByReplacingOccurrencesOfString:@" " withString:@""];
    const char * sourceChars = sourceString.UTF8String;
    NSMutableArray * arr = [NSMutableArray new];
    for (int i = 0; i < sourceString.length; i++) {
        [arr addObject:[NSString stringWithFormat:@"%c", sourceChars[i]]];
    }

    static NSString * alphabet = @"abcdefghijklmnopqrstuvwxyz";
    NSMutableDictionary * masterDictionary = [NSMutableDictionary new];
    for (int i = 0; i < alphabet.length; i++) {
        NSString * alphabetLetter = [alphabet substringWithRange:NSMakeRange(i, 1)];
        NSIndexSet * indexes = [arr indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
            if ([[(NSString *)obj lowercaseString] isEqualToString:alphabetLetter]) {
                return YES;
            }
            else {
                return NO;
            }
        }];

        masterDictionary[alphabetLetter] = @(indexes.count);
    }

    return masterDictionary;
}

ทำงานเหมือน:

NSDictionary * lettersNeeded = [self numberOfLettersNeededFromString:@"Hello\nI love cat\nI love dog\nI love mommy\nMommy loves daddy"];
NSLog(@"%@", lettersNeeded);

จะให้คุณ:

{a = 2; b = 0; c = 1; d = 4; e = 5; f = 0; g = 1; h = 1; i = 3; j = 0; k = 0; l = 6; m = 6; n = 0; o = 8; p = 0; q = 0; r = 0; s = 1; t = 1; u = 0; v = 4; w = 0; x = 0; y = 3; z = 0; }

ซึ่งฉันคิดว่าดีกว่าถ้าฉันมีข้อความจำนวนมากและฉันแค่ต้องการรู้จำนวนจดหมายที่ฉันต้องการ



2

Python 2, 154 ไบต์

import collections
c = collections.Counter()
for line in open("input.txt"):
    c |= collections.Counter(line.upper())
print "".join(sorted(c.elements()))

ยินดีต้อนรับสู่ PCG! ไซต์นี้รองรับไวยากรณ์ Markdown ซึ่งคุณสามารถใช้จัดรูปแบบรหัสของคุณเพื่อให้ดูดี: เพียงย่อหน้าแต่ละบรรทัดของช่องว่างรหัส 4
algorithmshark

คุณจะต้องเพิ่มอักขระที่จำเป็นในการนำเข้าคอลเล็กชัน
isaacg

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

คุณไม่มีคำsอธิบายท้ายimportประโยคและwithบล็อกนั้นไม่มีการย่อหน้า และเนื่องจากนี่คือรหัสกอล์ฟคุณจะได้รับประโยชน์อย่างมากจากการลบช่องว่างที่ไม่จำเป็นหากเป็นไปได้
Fraxtil

เนื่องจากนี่คือ code golf ให้ลบคำสั่ง with (แค่วนรอบการเรียกเพื่อเปิด) และฉันไม่คิดว่าองค์ประกอบต้องเรียงลำดับ
RemcoGerlich

2

C, 298 ไบต์

char c;
int j,n;
char C[26];
char D[26];
int main()
{
char a='a';
while((c=getchar())>=0)
{
c=tolower(c);
if(c>=a&&c<='z'){j=c-a;D[j]++;}
if(c=='\n'){
for(j=0;j<26;j++){
if(D[j]>C[j])
{C[j]=D[j];}
D[j]=0;
}
}
}
for(j=0;j<26;j++)
{
n=C[j];
while(n--)
{
putchar(a+j);
}
}
}

Array D มีจำนวนตัวอักษรสำหรับแต่ละบรรทัดจากนั้นจำนวนสูงสุดจะถูกคัดลอกไปยัง C

หมายเหตุ: ฉันตอบคำถามเมื่อวานนี้ แต่ตอนนี้ไม่อยู่ในรายการฉันอาจกดลบแทนการแก้ไขโดยไม่ได้ตั้งใจหรือไม่


มีขนาด 271 ไบต์เท่านั้น คุณมีการขึ้นบรรทัดใหม่ที่ไม่เกี่ยวข้องมากมาย นอกจากนี้คุณสามารถคุณสามารถละเว้นintจากและint main() int j,n;
nyuszika7h

นอกจากนี้คำตอบก่อนหน้าของคุณยังอยู่ที่นั่น
nyuszika7h

2

PHP, 143 ไบต์

สมมติว่าอินพุตถูกส่งผ่านในตัวแปร$s:

$i=explode("\n",$s);foreach(range('a','z')as$c){$x=array_map(function($l)use($c){return substr_count($l,$c);},$i);echo str_repeat($c,max($x));}

คำอธิบาย

สำหรับจดหมายที่เป็นไปได้แต่ละฉบับฉันกำลังทำแผนที่อาร์เรย์ที่มีรายการสตริงผ่านฟังก์ชั่นที่ผู้ใช้กำหนดซึ่งจะแทนที่แต่ละบรรทัดด้วยจำนวนอักขระที่ใช้ สำหรับตัวอักษร 'd' บรรทัด "แม่รักพ่อ" จะถูกแมปเป็น 3

หลังจากนั้นฉันก็พบว่ามีค่าสูงสุดภายในอาร์เรย์และตัวอักษรผลลัพธ์เพียงแค่นี้หลายครั้ง นี่คือเวอร์ชั่นหลายคู่สาย:

$i=explode("\n",$s);
foreach(range('A','Z')as $c){
    $x=array_map(function($l)use($c){
        return substr_count($l,$c);
    },$i);
    echo str_repeat($c,max($x));
}

1

Python (209 มีตัวอย่างรวมอยู่ด้วย 136 ไม่รวม):

from collections import*;c=Counter()
for i in ["Hello","I love cat", "I love Dog", "I love mommy", "Mommy loves daddy"]:
 for j in i.lower(): c[j]=max(c[j],list(i).count(j))
print "".join(sorted(c.elements()))

ฉันจะโพสต์ตัวอย่าง PYG ในบ่ายวันนี้


ฉันไม่รู้ว่าสายไพ ธ อนมีวิธีการนับจำนวน ... ฉันไม่คิดว่ามันถูกต้องหรือไม่ที่จะเปลี่ยนคำตอบของคำถามเป็นความรู้ที่ค้นพบใหม่? : p
Tal

@tal พวกเขาทำไม่ได้ มันเป็นวิธีการของรายการถ้าคุณมองใกล้ ๆ
ɐɔıʇǝɥʇuʎs

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