พิมพ์ uniqchars!


41

กำหนดสตริงที่ประกอบด้วยตัวอักษร ASCII พิมพ์ , ผลิตออกประกอบด้วยของตัวอักษรที่ไม่ซ้ำกันในการสั่งซื้อเดิม กล่าวอีกนัยหนึ่งเอาท์พุทเหมือนกันกับอินพุตยกเว้นว่าถ่านจะถูกลบออกถ้ามันปรากฏขึ้นก่อนหน้านี้

ไม่มีบิวด์อินสำหรับค้นหาองค์ประกอบเฉพาะในอาเรย์ที่สามารถใช้ได้ (ตัวอย่างเช่น MATLAB มีuniqueฟังก์ชั่นที่ทำเช่นนั้น) แนวคิดคือการทำด้วยตนเอง

รายละเอียดเพิ่มเติม:

  • ทั้งฟังก์ชั่นหรือโปรแกรมที่ได้รับอนุญาต
  • อินพุตและเอาต์พุตสามารถอยู่ในรูปแบบของฟังก์ชันอาร์กิวเมนต์, stdin / stdout (แม้สำหรับฟังก์ชัน) หรือผสมกัน
  • ถ้า stdin stdout หรือมีการใช้สตริงเป็นที่เข้าใจกันเพียงลำดับของตัวอักษร หากข้อโต้แย้งฟังก์ชั่นที่มีการใช้ลำดับของตัวอักษรอาจจะต้องมีการปิดล้อมในเครื่องหมายคำพูดหรือสัญลักษณ์เทียบเท่าว่าภาษาการเขียนโปรแกรมของการใช้ทางเลือกสำหรับการกำหนดสตริง
  • เอาต์พุตควรเป็นสตริงที่มีเฉพาะอักขระเฉพาะของอินพุต ดังนั้นจึงไม่มี linebreaks พิเศษช่องว่าง ฯลฯ ข้อยกเว้นเพียงอย่างเดียวคือ: หากเอาต์พุตถูกแสดงใน stdout ฟังก์ชันการแสดงผลส่วนใหญ่จะเพิ่มการต่อท้าย\n(เพื่อแยกสตริงออกจากสิ่งที่จะมาถัดไป) ดังนั้นหนึ่งต่อท้าย\nเป็นที่ยอมรับใน stdout
  • ถ้าเป็นไปได้โพสต์ลิงค์ไปยังล่าม / คอมไพเลอร์ออนไลน์เพื่อให้ผู้อื่นสามารถลองใช้รหัสของคุณ

นี่คือรหัสกอล์ฟดังนั้นรหัสที่สั้นที่สุดในหน่วยไบต์ชนะ

ตัวอย่างบางส่วนสมมติว่า stdin และ stdout:

  1. สตริงอินพุต:

    Type unique chars!
    

    สตริงเอาต์พุต:

    Type uniqchars!
    
  2. สตริงอินพุต

    "I think it's dark and it looks like rain", you said
    

    สตริงเอาต์พุต

    "I think'sdarloe,yu
    
  3. สตริงอินพุต

    3.1415926535897932384626433832795
    

    สตริงเอาต์พุต

    3.14592687
    

5
เพียงเพื่อตรวจสอบอีกครั้ง: กฎไม่มีบิวอินหมายความว่าไม่อนุญาตให้ตั้งค่าออบเจ็กต์หรือไม่
Sp3000

@ Sp3000 อนุญาตให้ตั้งค่าวัตถุ อย่าใช้ฟังก์ชั่นหรือวิธีการ (ถ้ามี) ที่ให้องค์ประกอบที่เป็นเอกลักษณ์แก่คุณ และอินพุต / เอาต์พุตควรเป็นสตริงไม่ได้ตั้งค่า tobjects
Luis Mendo

@ Sp3000 คุณคิดว่ามันน่าสนใจกว่าหรือไม่ที่จะลดจำนวนไบต์ทีละครึ่งถ้าไม่มีการใช้งานฟังก์ชั่นที่ตั้งไว้? หรือดีกว่าไม่เปลี่ยนกฎเมื่อมีการตั้งความท้าทาย?
Luis Mendo

5
ฉันคิดว่ามีเพียงคำตอบที่ฉันใช้ในปัจจุบันและฉันก็ไม่รังเกียจถ้าคุณเปลี่ยนมัน อย่างไรก็ตามฉันไม่แน่ใจว่าโบนัสแบบนี้จะเปลี่ยนไปมากเช่นฉันสงสัยว่า CJam จะสามารถใช้งานได้ใน <6 ไบต์โดยไม่ต้องตั้งค่า นอกจากนี้ฉันไม่แน่ใจว่าบรรทัดอยู่ระหว่าง builtin ซึ่งค้นหาองค์ประกอบที่ไม่ซ้ำกันและสร้างชุดจากองค์ประกอบจำนวนหนึ่ง ...
Sp3000

1
@ Sp3000 ใช่มันเป็นเส้นขอบเบลอ ฉันไม่ได้คาดหวังฟังก์ชั่นการตั้งค่า ฉันคิดว่าฉันจะออกจากการแข่งขันอย่างที่เป็นอยู่ตอนนี้
Luis Mendo

คำตอบ:


13

GolfScript 2 ไบต์

.&

หรืออีกทางหนึ่ง:

.|

ฉันโพสต์สิ่งนี้เมื่อไม่นานมานี้ในเคล็ดลับสำหรับการเล่นกอล์ฟในเธรดGolfScript มันทำงานโดยการทำซ้ำอินพุตสตริง (ซึ่งวางอยู่บนสแต็กโดยอัตโนมัติโดย GolfScript interpreter และซึ่งทำงานในรูปแบบส่วนใหญ่เช่นอาร์เรย์ของอักขระ) จากนั้นจึงตั้งค่าจุดตัด ( &) หรือสหภาพ ( |) ด้วยตัวมันเอง การใช้ตัวดำเนินการชุดกับอาร์เรย์ (หรือสตริง) จะยุบรายการที่ซ้ำกัน แต่เก็บรักษาลำดับขององค์ประกอบ


23

CJam, 3 ไบต์

qL|

Setwise หรือของอินพุตด้วยรายการว่าง ชุดปฏิบัติการ CJam สงวนรักษาลำดับองค์ประกอบ

ลองออนไลน์


ฉันสมมติว่ามันถูกต้องเพราะอนุญาตให้เซต แต่ฉันไม่แน่ใจ ...
Sp3000

ฉลาดมาก! ฉันรู้ว่า CJam จะดีที่สุดคนหนึ่ง แต่ฉันไม่ได้คาดหวังเพียงแค่ 3 ไบต์!
Luis Mendo

19

C # 6, 18 + 67 = 85 ไบต์

ต้องการusingข้อความนี้:

using System.Linq;

วิธีการที่เกิดขึ้นจริง:

string U(string s)=>string.Concat(s.Where((x,i)=>s.IndexOf(x)==i));

วิธีนี้จะบันทึกตัวอักษรบางตัวโดยกำหนดฟังก์ชั่นเป็นแลมบ์ดาซึ่งได้รับการสนับสนุนใน C # 6 นี่คือลักษณะที่จะดูใน C # pre-6 (แต่ไม่ได้รับการดูแล):

string Unique(string input)
{
    return string.Concat(input.Where((x, i) => input.IndexOf(x) == i));
}

มันทำงานอย่างไร: ฉันเรียกWhereเมธอดบนสตริงที่มีแลมบ์ดาพร้อมอาร์กิวเมนต์สองตัว: xแทนองค์ประกอบปัจจุบันซึ่งiแสดงถึงดัชนีขององค์ประกอบนั้น IndexOfส่งกลับค่าดัชนีแรกของถ่านที่ส่งไปให้เสมอดังนั้นหากiไม่เท่ากับดัชนีแรกของxมันจะเป็นอักขระที่ซ้ำกันและจะต้องไม่รวมอยู่ด้วย


3
ฉันจะไม่คาดหวังว่า C # จะสั้นขนาดนี้ ยอดเยี่ยมมาก!
Alex A.

อืม ฉันคิดว่าคุณควรส่งโปรแกรมที่สมบูรณ์ (พร้อมกับstatic void Mainอื่น ๆ )
Timwi

3
@Timwi ความท้าทายนี้ระบุว่า "อนุญาตให้ใช้ฟังก์ชันหรือโปรแกรมใดก็ได้"
hvd

C # อนุญาตให้ใช้วิธีที่สั้นกว่านี้ได้เช่นกันโดยใช้ LINQ ฉันโพสต์คำตอบที่แข่งขัน :)
hvd

@hvd Nice one! +1
ProgramFOX

14

เรติน่า 14 ไบต์

+`((.).*)\2
$1

แต่ละบรรทัดควรอยู่ในไฟล์แยกต่างหากหรือคุณสามารถใช้-sแฟล็กเพื่ออ่านจากไฟล์เดียว

เพื่ออธิบายเราจะใช้เวอร์ชันที่ยาวกว่านี้ แต่ง่ายกว่า:

+`(.)(.*)\1
$1$2

บรรทัดแรกคือ regex เพื่อให้ตรงกับ ( +`เป็นสตริงการกำหนดค่าที่ยังคงทำงานจนกว่าจะมีการเปลี่ยนทั้งหมด) regex ค้นหาอักขระ (เราจะเรียกมันว่า C) ตามด้วยอักขระศูนย์หรือมากกว่านั้นตามด้วย C. วงเล็บแสดงถึงกลุ่มจับภาพดังนั้นเราจึงแทนที่การจับคู่ด้วย C ( $1) และอักขระในระหว่าง ( $2) ลบซ้ำของ C.

ตัวอย่างเช่นหากสตริงป้อนเข้าuniqueการเรียกใช้ครั้งแรกจะจับคู่uniquกับuและniqเป็น$1และ$2ตามลำดับ จากนั้นก็จะเข้ามาแทนที่ substring จับคู่ในการป้อนข้อมูลเดิมที่มีให้uniquniqe


3
ฉันกำลังมองหา regex เพื่อทำสิ่งนี้; ฉันไม่ได้ตระหนักว่ามันสั้นมาก! +1
ETHproductions

13

Perl, 21 (20 ไบต์ + -p)

s/./!$h{$&}++&&$&/eg

การใช้งาน:

perl -pe 's/./!$h{$&}++&&$&/eg' <<< 'Type unique chars!'
Type uniqchars!

1
คุณสามารถประหยัด 1 ไบต์กวน$h{$&}และการใช้ตรรกะและแทนที่จะเป็นผู้ประกอบการ ternary:s/./!$h{$&}++&&$&/eg
คอส

@ kos ถ้าคุณถามฉันฉันจะบอกคุณว่าฉันลอง 100% และจบลงด้วย1s ในผลลัพธ์ แต่มันไม่ได้! ขอขอบคุณอัปเดต!
Dom Hastings

1
โหวตขึ้นแล้ว :) ฉันคิดว่าคุณลองแล้วs/./$h{$&}++||$&/eg(ตอนแรกฉันก็ล้มลงเหมือนกัน) ความอัปยศเพราะนั่นจะเป็นอีกไบต์ที่บันทึกไว้
kos

11

มักกะโรนี 0.0.2 , 233 ไบต์

set i read set f "" print map index i k v return label k set x _ set _ slice " " length index f e 1 1 set f concat f wrap x return label e set _ slice " " add _ multiply -1 x 1 1 return label v set _ unwrap slice i _ add 1 _ 1 return
  • สร้างภาษา "ต่อต้านการเล่นกอล์ฟ": ตรวจสอบ
  • กอล์ฟมันต่อไป: ตรวจสอบ

นี่เป็นโปรแกรมเต็มรูปแบบซึ่งอินพุตจาก STDIN และเอาต์พุตบน STDOUT

เวอร์ชันที่ห่อหุ้มสำหรับค่าสุนทรียะ:

set i read set f "" print map index i k v return label k set x _ set _ slice "
" length index f e 1 1 set f concat f wrap x return label e set _ slice " " add
_ multiply -1 x 1 1 return label v set _ unwrap slice i _ add 1 _ 1 return

และรุ่นที่ "วิจารณ์" และไม่อัปโหลด (ไม่มีความคิดเห็นใน Macaroni ดังนั้นฉันจึงใช้ตัวอักษรสตริงเปล่า):

set input read                  "read line from STDIN, store in 'input' var"
set found ""                    "we need this for 'keep' below"
print map index input keep val  "find indeces to 'keep', map to values, print"
return

label keep
    "we're trying to determine which indeces in the string to keep. the special
     '_' variable is the current element in question, and it's also the value
     to be 'returned' (if the '_' variable is '0' or empty array after this
     label returns, the index of the element is *not* included in the output
     array; otherwise, it is"
    set x _ set _ slice
        " "
        length index found exists
        1
        1
    "now we're using 'index' again to determine whether our '_' value exists in
     the 'found' array, which is the list of letters already found. then we
     have to apply a boolean NOT, because we only want to keep values that do
     NOT exist in the 'found' array. we can 'invert' a boolean stored as an
     integer number 'b' (hence, 'length') with 'slice(' ', b, 1, 1)'--this is
     equivalent to ' '[0:1], i.e. a single-character string which is truthy, if
     'b' was falsy; otherwise, it results in an empty string if 'b' was truthy,
     which is falsy"
    set found concat found wrap x  "add the letter to the 'found' array"
return

label exists
    set _ slice
        " "
        add _ multiply -1 x
        1
        1
    "commentary on how this works: since 0 is falsy and every other number is
     truthy, we can simply subtract two values to determine whether they are
     *un*equal. then we apply a boolean NOT with the method described above"
return

label val
    set _ unwrap slice input _ add 1 _ 1  "basically 'input[_]'"
return

(นี่เป็นโปรแกรมแรกของ Macaroni จริง ๆ (ที่ทำอะไรบางอย่างจริงๆ)! \ o /)


5
•ตั้งชื่อภาษาที่ตลกและเหมาะสม: ตรวจสอบ
Luis Mendo

11

JavaScript ES7, 37 33 25 ไบต์

วิธีการง่ายๆที่ใช้ ES6 Setและ ES7 Array comprehensions spread operator:

s=>[...new Set(s)].join``

22 ไบต์น้อยกว่าindexOfวิธีการ ทำงานในกรณีทดสอบจำนวนหนึ่ง


ช่องว่างรอบforการแสดงออกของที่ไม่จำเป็นและคุณสามารถทำให้มันเป็นฟังก์ชั่นที่ไม่ระบุชื่อเป็นบางส่วนแก้ปัญหาอื่น ๆ s=>[for(c of Set(s))c].join``ได้: (อัปเดตซีด: ไม่แน่ใจ 100% แต่newคำหลักดูเหมือนไม่จำเป็นเช่นกัน)
จัดการ

ไม่แน่ใจเกี่ยวกับกฎที่มีฟังก์ชั่นอานนท์และใช้พื้นที่ได้ดี
azz

รหัส Transpiled โดยไม่newส่งผลให้Uncaught TypeError: Constructor Set requires 'new'ใน Google Chrome
azz

โปรดแก้ตัวความไม่รู้ของฉัน แต่ตัวกรองนี้มีค่าที่ไม่ซ้ำกันในจุดใด ดูเหมือนว่ามันเพียงแค่แปลงสตริงเป็นชุดจากนั้นรวมค่าที่เกิดขึ้นในสตริงเดิมอีกครั้ง
Patrick Roberts

@PatrickRoberts เป็นการแปลงเป็นชุด ชุดตามคำนิยามไม่มีรายการซ้ำซ้อน
edc65

8

C # 6 - 18 + 46 = 64

using System.Linq;

แล้ว

string f(string s)=>string.Concat(s.Union(s));

Enumerable.Unionวิธีการระบุนามสกุลว่าองค์ประกอบจะถูกส่งกลับในการสั่งซื้อเดิม:

เมื่อวัตถุที่ส่งกลับโดยวิธีนี้มีระบุสหภาพระบุเป็นครั้งแรกและครั้งที่สองในการสั่งซื้อที่และอัตราผลตอบแทนแต่ละองค์ประกอบที่ไม่ได้รับผลแล้ว

ตั้งค่าการดำเนินการที่ไม่ได้มีวัตถุประสงค์เพื่อค้นหาค่าที่ไม่ซ้ำกันโดยเฉพาะเพื่อให้สามารถตัดสินโดยคำตอบอื่น ๆ


เป็นคนดีฉันกำลังคิดstring u(string s)=>String.Join("",s.Distinct());แต่นั่นอีกหน่อย
germi

@Germi ขอบคุณ มีคำตอบที่ใช้Distinct()อยู่แล้ว แต่ถูกลบเนื่องจากDistinct()ไม่ได้รับอนุญาตในการท้าทายนี้เนื่องจากเป็นวิธีการที่ต้องการหาค่าที่ไม่ซ้ำกันโดยเฉพาะ
hvd

อ่า ... มองข้ามบิตนั้น)
58

คือs => string.Concat(s.Union(s))ถูกต้อง? นั่นคือผู้รับมอบสิทธิ์จะถูกส่งไปFunc<string, string>ยังอาร์กิวเมนต์
Tyler StandishMan

@TylerStandishMan หากถูกต้องฉันคาดหวังว่าจะมีผู้คนจำนวนมากใช้ประโยชน์จากมันและฉันไม่เคยเห็นมาก่อนดังนั้นฉันจึงไม่คิดว่าจะเป็นเช่นนั้น แต่บางทีมันควรจะถูกต้อง - ดูเหมือนว่ามีบางสิ่งที่คุ้มค่าในการตรวจสอบ Meta หากคุณสนใจ
hvd

7

JavaScript ES6, 47 ไบต์

f=s=>s.replace(/./g,(e,i)=>s.indexOf(e)<i?'':e)

การทดสอบด้านล่างใช้งานได้กับเบราว์เซอร์ทั้งหมด

f=function(s){
  return s.replace(/./g,function(e,i){
    return s.indexOf(e)<i?'':e
  })
}

run=function(){document.getElementById('output').innerHTML=f(document.getElementById('input').value)};document.getElementById('run').onclick=run;run()
<input type="text" id="input" value="Type unique chars!" /><button id="run">Run</button><br />
<pre id="output"></pre>


สิ่งที่ไม่<i?'':eเป็นส่วนหนึ่งทำอย่างไร
DanTheMan

1
มันเป็นผู้ประกอบการที่สาม หากอินสแตนซ์แรกของตัวละครeอยู่หน้าดัชนีปัจจุบันiจะส่งคืนสตริงว่างดังนั้นการกำจัดอักขระ หากนั่นเป็นอินสแตนซ์แรกมันจะส่งคืนeและไม่มีการเปลี่ยนแปลงใด ๆ
NinjaBearMonkey

7

MATLAB, 23

 @(n)union(n,n,'stable')

ทำการ "ตั้งค่าสหภาพ" ของสตริงอินพุตด้วยตัวเองโดยใช้เมธอด 'เสถียร' ซึ่งไม่เรียงลำดับแล้วพิมพ์

ใช้งานได้เนื่องจากunionส่งคืนเฉพาะค่าที่ไม่ซ้ำกันหลังจากการผสาน ถ้าคุณunionใช้สตริงตัวเองมันจะสร้างสตริงที่เหมือนType unique chars!Type unique chars!กันก่อนแล้วจึงลบรายการที่ซ้ำกันทั้งหมดโดยไม่ต้องเรียงลำดับ

ไม่จำเป็นต้องunique:)


uniqueไม่อนุญาตขอโทษ! มันอยู่ในคำนิยาม challange
หลุยส์เมนโด

พลาดแล้วไม่เป็นไร
Tom Carpenter

ตามคำตอบของ Sp3000 ฉันขอแนะนำsetdiffด้วย'stable'ตัวเลือกได้ไหม
Luis Mendo

1
ดี! และใช่คุณสามารถลบdispเพราะคุณมีฟังก์ชั่นที่ส่งกลับสตริงซึ่งอนุญาตให้ทำได้
Luis Mendo

1
คุณยังสามารถใช้intersectกับ'stable'เพื่อให้ได้ผลเช่นเดียวกัน ฉันกำลังจะเขียนสิ่งนั้น แต่ให้คำตอบนี้มันไม่ได้เป็นแบบดั้งเดิมเลย
rayryeng - Reinstate Monica

7

> <> , 16 ไบต์

i:0(?;:::1g?!o1p

> <> ไม่มีสตริงดังนั้นเราใช้ประโยชน์จาก codebox เนื่องจากลักษณะวงแหวนของ> <> การทำงานต่อไปนี้ในลูป

i         Read a char
:0(?;     Halt if EOF
:::       Push three copies of the char
1g        Get the value at (char, 1), which is 0 by default
?!o       Print the char if the value was nonzero
1p        Set the value at (char, 1) to char

โปรดทราบว่าสิ่งนี้ใช้ความจริงที่ว่าอินพุตมี ASCII ที่พิมพ์ได้เท่านั้นเนื่องจากจะไม่ทำงานหากมี ASCII 0 อยู่


1
....... อันนี้ยอดเยี่ยม ฉันหวังว่าฉันจะคิดถึงสิ่งนี้ ฉันจะรวมเวอร์ชัน Befunge ในคำตอบของฉัน แต่ไม่ใช่เป็นหลัก แก้ไข: ในความคิดที่สองนี้จะไม่ทำงานเพราะ Befunge ไม่มีพื้นที่โค้ดไม่ จำกัด Dangit!
El'endia Starman

@ El'endiaStarman ฉันคิดว่าคำตอบของบีมก็ทำสิ่งเดียวกันดังนั้นโชคไม่ดีที่ฉันไม่สามารถบอกได้ว่าฉันเป็นคนแรก: P
Sp3000

อ่าใช่ฉันคิดว่าคุณพูดถูก คำอธิบายของคุณชัดเจนขึ้น
El'endia Starman


5

องค์ประกอบ , 22 19 18 ไบต์

_'{"(3:~'![2:`];'}

ตัวอย่างอินพุต / เอาต์พุต: hello world->helo wrd

วิธีนี้ใช้งานได้โดยการประมวลผลสตริงอักขระหนึ่งตัวในแต่ละครั้งและติดตามดูว่าอักขระตัวใดเคยเห็นมาก่อน

_'{"(3:~'![2:`];'}
_                        input line
 '                       use as conditional
  {              }       WHILE loop
   "                     retrieve string back from control (c-) stack
    (                    split to get the first character of (remaining) string
     3:                  a total of three copies of that character
       ~                 retrieve character's hash value
        '                put on c-stack
         !               negate, gives true if undef/empty string
          [   ]          FOR loop
           2:`           duplicate and output
               ;         store character into itself
                '        put remaining string on c-stack as looping condition


4

Python 3, 44

r=''
for c in input():r+=c[c in r:]
print(r)

สร้างอักขระสตริงเอาต์พุตrตามอักขระรวมถึงอักขระcจากอินพุตเฉพาะเมื่อเรายังไม่เห็นมัน

งูหลาม 2 จะเป็น 47 แพ้ 4 ตัวอักษรด้วยraw_inputและบันทึก 1 ไม่จำเป็นต้อง parers printสำหรับ


ฉันทามติตอนนี้ดูเหมือนว่าคุณสามารถใช้inputใน Python 2 เพื่อให้คุณสามารถทำให้ไบต์สั้นลง
mbomb007

4

APL, 3

∊∪/

สิ่งนี้ใช้การรวมกัน (∪) ระหว่างแต่ละองค์ประกอบของเวกเตอร์การได้รับการวนซ้ำที่มีผลในการลบรายการที่ซ้ำกัน

ทดสอบบนtryapl.org

อันเก่า:

~⍨\

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


Nitpicking: "และอินพุต / เอาต์พุตควรเป็นสตริง" Luis กล่าว "Unione ลด" ส่งคืนอาร์เรย์ที่ซ้อนกันไม่ใช่สตริง O :-)
lstefano

คุณถูกต้องเพิ่ม a ที่จุดเริ่มต้นเพื่อแก้ไข
Moris Zucca

3

Perl, 54 27 ไบต์

map{$h{$_}||=print}<>=~/./g
123456789012345678901234567

ทดสอบ:

$ echo Type unique chars! | perl -e 'map{$h{$_}||=print}<>=~/./g'
Type uniqchars!
$

1
print exists($h{$_})?"":$_$h{$_}||print
จัดการ

มีการแทรก unicode → char ในการสร้างการแสดงผลเสียหรือไม่?
สตีฟ

1
การใช้โมดิฟายเออร์ปรับแต่งข้อความจะช่วยให้คุณประหยัดไบต์บางส่วนพร้อมกับข้อเสนอแนะของ @ manatwork $h{$_}||=printและการใช้งาน<>=~/./gควรช่วยประหยัดมากขึ้นเช่นกัน!
Dom Hastings

1
ไม่ฉันใส่มันด้วยความหมายของ "เปลี่ยนเป็น"
จัดการ

1
การเปลี่ยนไปmapเป็นการปรับปรุงการประหยัด: map{$h{$_}||=print}<>=~/./g
จัดการ

3

PHP, 72 ไบต์ 84 ไบต์

<?foreach(str_split($argv[1])as$c)$a[$c]=0;echo join('',array_keys($a));

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

ขอบคุณ Ismael Miguel สำหรับstr_splitคำแนะนำ


1
<?foreach(str_split($argv[1])as$c)$a[$c]=0;echo join('',array_keys($a));สั้นลงและทำเช่นเดียวกัน
Ismael Miguel

พบว่าวนรอบสั้นลง: while($c=$argv[1][$i++*1]). foreachนี้แทนที่ทั้งหมด ทุกอย่างอื่นเหมือนกัน
Ismael Miguel

ฉันพยายามสิ่งที่คล้ายกันครั้งแรก แต่งดเว้นจากมันเพราะมันจะหยุดในลักษณะที่ coerces "false" "0"คือ ลองใช้ "abc0def" เป็นอินพุต
Fabian Schmengler

คุณพูดถูก แน่นอนว่ามันมีวิธีการแก้ปัญหาสำหรับค่าใช้จ่ายไม่เกิน 2 ไบต์
Ismael Miguel

3

Pyth, 7 ไบต์

soxzN{z

pseudocode:

z = อินพุต

ผลรวมของดัชนีเรียงตามดัชนีใน z ของ N บนชุด z


3

จูเลีย45 45ไบต์

s->(N="";[i∈N?N:N=join([N,i])for i=s];N)

เวอร์ชั่นเก่า:

s->(N={};for i=s i∈N||(N=[N,i])end;join(N))

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

โซลูชันสำรอง 45 ไบต์โดยใช้การเรียกซ้ำและ regex:

f=s->s!=(s=replace(s,r"(.).*\K\1",""))?f(s):s

Julia อายุ 17 ไบต์

(รุ่นสำรอง)

s->join(union(s))

สิ่งนี้ใช้unionแทนuniqueคำตอบโดยทั่วไป- ฉันไม่คิดว่านี่เป็นคำตอบที่ "จริง" เพราะฉันแปลว่า "ไม่ได้ใช้unique" เพื่อหมายถึง "อย่าใช้ฟังก์ชั่นในตัวเดียวที่มีผลต่อการคืนค่าที่ไม่ซ้ำกัน องค์ประกอบ"


ฉันมีความคิดคล้าย ๆ กัน แต่ก็ไม่กระชับ เยี่ยมมาก!
Alex A.

3

Java, 78 ไบต์

String f(char[]s){String t="";for(char c:s)t+=t.contains(c+"")?"":c;return t;}

การวนรอบอย่างง่ายขณะตรวจสอบเอาต์พุตสำหรับอักขระที่มีอยู่แล้ว char[]รับข้อมูลเป็น


3

C, 96 ไบต์

#include<stdio.h> 
int c,a[128];main(){while((c=getchar())-'\n')if(!a[c])a[c]=1,putchar(c);}

สิ่งนี้ใช้อาร์เรย์ของจำนวนเต็มซึ่งจัดทำดัชนีโดยหมายเลขอักขระ ASCII อักขระจะถูกพิมพ์ต่อเมื่อสถานที่ในอาร์เรย์นั้นถูกตั้งค่าเป็น FALSE หลังจากพบอักขระใหม่แต่ละตัวแล้วสถานที่ในอาร์เรย์นั้นถูกตั้งค่าเป็น TRUE การดำเนินการนี้จะใช้บรรทัดข้อความจากอินพุตมาตรฐานยกเลิกโดยบรรทัดใหม่ มันไม่สนใจอักขระที่ไม่ใช่ ASCII


Ungolfed:

#include<stdio.h>
#include<stdbool.h>

int main(void)
{
  int i, c;
  int ascii[128];
  for (i = 0; i < 128; ++i) {
    ascii[i] = false;
  }
  while ((c = getchar()) != '\n') {
    if (ascii[c] == false) {
      ascii[c] = true;
      putchar(c);
    }
  }
  puts("\n");
  return(0);
}

3

C - 58

ขอบคุณ @hvd และ @AShelly สำหรับการบันทึกอักขระจำนวนมาก มีหลายวิธีที่แนะนำให้ทำให้สั้นกว่าเดิมมาก:

// @hvd     - always copy to q but only increment q if not found
g(char*s,char*r){char*q=r;for(;*q=*s;q+=q==strchr(r,*s++));}

// @AShelly - keep a histogram of the usage of each character
h(char*s){int a[128]={0};for(;*s;s++)a[*s]++||putchar(*s);}

// @hvd     - modify in place
i(char*s){char*q=s,*p=s;for(;*q=*p;q+=q==strchr(s,*p++));}

// original version - requires -std=c99
void f(char*s,char*r){for(char*q=r;*s;s++)if(!strchr(r,*s))*q++=*s;}

ในขณะที่คุณสามารถเห็นการปรับเปลี่ยนในสถานที่ที่ดูเหมือนว่าจะสั้นที่สุด (จนถึงตอนนี้!) โปรแกรมทดสอบรวบรวมโดยไม่มีคำเตือนใช้ gcc test.c

#include <stdlib.h> // calloc
#include <string.h> // strchr
#include <stdio.h>  // puts, putchar

// 000000111111111122222222223333333333444444444455555555556666666666
// 456789012345678901234567890123456789012345678901234567890123456789

// @hvd     - always copy to q but only increment q if not found
g(char*s,char*r){char*q=r;for(;*q=*s;q+=q==strchr(r,*s++));}

// @AShelly - keep a histogram of the usage of each character
h(char*s){int a[128]={0};for(;*s;s++)a[*s]++||putchar(*s);}

// @hvd     - modify in place
i(char*s){char*q=s,*p=s;for(;*q=*p;q+=q==strchr(s,*p++));}

/* original version - commented out because it requires -std=c99
void f(char*s,char*r){for(char*q=r;*s;s++)if(!strchr(r,*s))*q++=*s;}
*/

// The test program:
int main(int argc,char*argv[]){
  char *r=calloc(strlen(argv[1]),1); // make a variable to store the result
  g(argv[1],r);                      // call the function
  puts(r);                           // print the result

  h(argv[1]);                        // call the function which prints result
  puts("");                          // print a newline

  i(argv[1]);                        // call the function (modifies in place)
  puts(argv[1]);                     // print the result
}

ขอบคุณสำหรับความช่วยเหลือ ฉันซาบซึ้งกับคำแนะนำทั้งหมดที่ให้สั้นลงมาก!


ดีเนื่องจากรหัสของคุณอยู่แล้วไม่ได้เป็น C ที่ถูกต้องได้รับการยอมรับโดยคอมไพเลอร์ C ผ่อนปรน: คุณสามารถประกาศrเป็นint(และละเว้นint) f(s,r)char*s;{...}เพื่อบันทึกไบต์บางส่วน: แต่มัน จำกัด รหัสของคุณไว้ที่แพลตฟอร์มที่char*มีขนาดเท่าintกันและแน่นอนว่าคอมไพเลอร์มีความผ่อนปรนเหมือนของคุณและของฉัน
hvd

@hvd นั่นมันชั่วร้าย! ฉันยินดีที่จะเริ่มต้นค่าตอบแทนเพราะฉันไม่ได้ใช้มัน แต่นั่นเป็นสิ่งที่หลีกเลี่ยงมากกว่าที่ฉันอยากจะเป็น ฉันคิดว่าฉันชอบที่จะทำให้มันเข้ากันได้มากกว่าที่จะไปให้ไกล! ขอบคุณที่นำกลับไปด้านแสง
Jerry Jeremiah

คุณสามารถบันทึกหนึ่งอักขระโดยแทนที่if(x)yด้วยx?y:0
ugoren

ต่อไปนี้เป็นฟังก์ชั่น 60 ถ่านที่เขียนไป stdout แทนพารามิเตอร์อาร์เรย์: f(char*s){int a[128]={0};for(;*s;s++)a[*s]++?0:putchar(*s);}
AShelly

คุณสามารถคัดลอกลงในแบบไม่มีเงื่อนไข*qและเพิ่มขึ้นเฉพาะqเมื่อตัวละครปรากฏขึ้นก่อนหน้านี้ซึ่งอนุญาตให้ทำการบรรจุได้มากกว่ากัน: void f(char*s,char*r){for(char*q=r;*q=*s;strchr(r,*s++)<q||q++);}(โปรดทราบว่าstrchr(r,*s++)<qมีการกำหนดไว้อย่างดีเสมอไม่มี UB อยู่ที่นั่นเพราะstrchrไม่สามารถส่งคืนNULLในรุ่นนี้) ยกเว้นประเภทการส่งคืน มันสั้นกว่ารุ่นของ @ AShelly
hvd


2

CJam, 9

Lq{1$-+}/

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

คำอธิบาย:

L       push an empty array/string
q       read the input
{…}/    for each character in the input
  1$    copy the previous string
  -     subtract from the character (set difference),
         resulting in the character or empty string
  +     append the result to the string

อีกรุ่น 13 ไบต์:

Lq{_2$#)!*+}/

สิ่งนี้ไม่ได้ทำอะไรที่เกี่ยวข้องกับฉาก ลองออนไลน์

คำอธิบาย:

L       push an empty array/string
q       read the input
{…}/    for each character in the input
  _     duplicate the character
  2$    copy the previous string
  #)    find the index of the character in the string and increment it
  !     negate, resulting in 0 if the character was in the string and 1 if not
  *     repeat the character that many times
  +     append the result to the string

2

TI-BASIC, 49 ไบต์

Input Str1
"sub(Str1,X,1→Y₁
Y₁(1
For(X,2,length(Str1
If not(inString(Ans,Y₁
Ans+Y₁
End
Ans

ตัวแปรสมการไม่ค่อยมีประโยชน์เนื่องจากพวกมันใช้เวลา 5 ไบต์ในการจัดเก็บ แต่Y₁มีประโยชน์ในที่นี้เป็นXอักขระตัวที่สามของสตริงการบันทึก 3 ไบต์ เนื่องจากเราไม่สามารถเพิ่มลงในสตริงว่างใน TI-BASIC เราจึงเริ่มต้นสตริงด้วยอักขระตัวแรกของ Str1 จากนั้นวนซ้ำส่วนที่เหลือของสตริงเพิ่มอักขระทั้งหมดที่ยังไม่พบ

prgmQ
?Why no empty st
rings? Because T
I...
Why noemptysrig?Bcau.

2

Matlab ขนาด 46 ไบต์

มันใช้ฟังก์ชั่นที่ไม่ระบุชื่อโดยมีอาร์กิวเมนต์ของฟังก์ชันเป็นอินพุตและเอาต์พุต:

@(s)eval('s(~any(triu(bsxfun(@eq,s,s''),1)))')

(ฉันไม่สามารถทำให้สิ่งนี้ทำงานได้ในล่ามออนไลน์ของ Octave)

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

>> @(s)eval('s(~any(triu(bsxfun(@eq,s,s''),1)))')
ans = 
    @(s)eval('s(~any(triu(bsxfun(@eq,s,s''),1)))')

>> ans('Type unique chars!')
ans =
Type uniqchars!

นั่นเป็นความคิดของฉันเช่นกัน :) - คุณไม่ต้องการ,1ด้วยanybtw
Jonas

@ Jonas ขอบคุณ! Alrhough มันยากที่จะมองผ่านความยุ่งเหยิงของวงเล็บ1นั่นคือสำหรับtriu (ฉันจำเป็นต้องลบเส้นทแยงมุม) ไม่ใช่สำหรับany
Luis Mendo

2

Befunge -93, 124 bytes

v
<v1p02-1
0_v#`g00: <0_@#+1::~p
 1>:1+10p2+0g-!#v_v
g `#v_10g0^       >:10g00
 ^0g 00$        <
 ^  >:,00g1+:00p1+:1+01-\0p

ทดสอบในล่ามออนไลน์นี้


นี่ยากกว่าที่ฉันคาดไว้ ฉันจะโพสต์คำอธิบายที่สมบูรณ์กว่าในวันพรุ่งนี้หากใครต้องการให้ฉัน แต่นี่คือภาพรวมของสิ่งที่รหัสของฉันทำ

  • อักขระที่เห็นที่ไม่ซ้ำกันจะถูกเก็บไว้ในแถวแรกโดยเริ่มจาก2,0และขยายไปทางขวา สิ่งนี้จะถูกตรวจสอบเพื่อดูว่าอักขระปัจจุบันซ้ำกันหรือไม่
  • จำนวนตัวอักษรที่ไม่ซ้ำกันเห็นจนถึงถูกเก็บไว้ในและวงเคาน์เตอร์เช็คอินสำหรับที่ซ้ำกันจะถูกเก็บไว้ใน0,01,0
  • เมื่อเห็นอักขระที่ไม่ซ้ำกันอักขระนั้นจะถูกเก็บไว้ในแถวแรกพิมพ์ออกมาและตัวนับ0,0จะเพิ่มขึ้น
  • เพื่อหลีกเลี่ยงปัญหาการอ่านในช่องว่างที่มีอยู่ (ASCII 32) ฉันใส่อักขระที่สอดคล้องกับ -1 (จริง ๆ , 65536) ในช่องถัดไปสำหรับอักขระที่ไม่ซ้ำกันถัดไป

2

PHP, 56 54

// 56 bytes
<?=join('',array_flip(array_flip(str_split($argv[1]))));

// 54 bytes
<?=join(!$a='array_flip',$a($a(str_split($argv[1]))));

การหาคำตอบของ @fschmengler โดยใช้array_flipสองครั้ง - รุ่นที่สองใช้วิธีการแปรผันและอาศัยการสตริสตริงเป็นจริงโดยปฏิเสธว่าเป็นเท็จจากนั้นจึงแปลงกลับเป็นสตริงว่างในอาร์กิวเมนต์แรกเพื่อบันทึกสองไบต์ในวินาที ราคาถูก!


2

Haskell , 29 ไบต์

หนึ่งซับใน Nestable ไม่มีชื่อตัวแปร:

foldr(\x->(x:).filter(x/=))[]

จำนวนเดียวกันที่บันทึกไว้ในฟังก์ชันที่ชื่อfเป็นการประกาศระดับบนสุด:

f(x:t)=x:f[y|y<-t,x/=y];f_=[]

โปรดทราบว่ามีการเพิ่มประสิทธิภาพการโกงเล็กน้อยที่ฉันไม่ได้ทำด้วยจิตวิญญาณของความดี: มันยังได้รับอนุญาตทางเทคนิคตามกฎของความท้าทายนี้ที่จะใช้การเข้ารหัสอินพุตและเอาต์พุตที่แตกต่างกันสำหรับสตริง โดยตัวแทนใด ๆstringโดยการเข้ารหัสของคริสตจักรบางส่วนนำไปใช้\f -> foldr f [] string :: (a -> [b] -> [b]) -> [b](กับด้านอื่น ๆ ของ bijection ที่มีให้โดยฟังก์ชั่น($ (:))) นี้ได้รับความแข็งแรงเล่นกอล์ฟลงไป($ \x->(x:).filter(x/=))เพียง 24 ตัวอักษร

ฉันหลีกเลี่ยงการโพสต์การตอบกลับ 24 ตัวอักษรเป็นทางการของฉันเพราะพยายามแก้ปัญหาข้างต้นบนล่ามด้านบนในfoldr(\x->(x:).filter(x/=))[]"Type unique chars!"ขณะที่วิธีการแก้ปัญหา golfed จะเขียนแทน:

($ \x->(x:).filter(x/=))$ foldr (\x fn f->f x (fn f)) (const []) "Type unique chars!"

เป็นชวเลขสำหรับการประกาศตามตัวอักษรซึ่งจะบ้ามากขึ้น:

($ \x->(x:).filter(x/=))$ \f->f 'T'.($f)$ \f->f 'y'.($f)$ \f->f 'p'.($f)$ \f->f 'e'.($f)$ \f->f ' '.($f)$ \f->f 'u'.($f)$ \f->f 'n'.($f)$ \f->f 'i'.($f)$ \f->f 'q'.($f)$ \f->f 'u'.($f)$ \f->f 'e'.($f)$ \f->f ' '.($f)$ \f->f 'c'.($f)$ \f->f 'h'.($f)$ \f->f 'a'.($f)$ \f->f 'r'.($f)$ \f->f 's'.($f)$ \f->f '!'.($f)$ const[]

แต่มันเป็นรุ่นที่ถูกต้องสมบูรณ์ของโครงสร้างข้อมูลที่แสดงว่าเป็นฟังก์ชันที่บริสุทธิ์ (แน่นอนว่าคุณสามารถใช้งานได้\f -> foldr f [] "Type unique chars!"เช่นกัน แต่มันอาจผิดกฎหมายเนื่องจากมันใช้รายการเพื่อเก็บข้อมูลจริงดังนั้นส่วน foldr ของมันก็ควรจะประกอบด้วยฟังก์ชัน "คำตอบ" ซึ่งนำไปสู่อักขระมากกว่า 24 ตัว)

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