ใช้งานฟังก์ชั่นเหมือน t9


10

ความท้าทายของคุณในวันนี้คือการใช้ฟังก์ชั่นที่เหมือนt9

คุณจะใช้ฟังก์ชั่นที่จะมีเพียง 2 พารามิเตอร์
คุณจะได้รับหมายเลขโทรศัพท์ 1 หมายเลขในสายอักขระและเนื้อหาของไฟล์ข้อความพร้อมรายการคำศัพท์ (ไม่ต้องใช้สไตล์บรรทัดใหม่เฉพาะเจาะจง)
คุณสามารถใช้ลิงค์https://raw.githubusercontent.com/eneko/data-repository/master/data/words.txtเพื่อทดสอบการใช้งานหรือใช้/usr/share/dict/words(ตรวจสอบไฟล์ข้อความที่มีรายการคำ [ปิด]สำหรับข้อมูลเพิ่มเติม ข้อมูล).

คุณสามารถสันนิษฐานได้ว่าคุณจะได้รับอย่างน้อย 2 หมายเลข

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

หากไม่มีการแข่งขันพบคุณสามารถกลับรายการว่างnull/ หรือnil0

โปรดจำไว้ว่าคีย์โทรศัพท์มือถือนั้นถูกจับคู่กับตัวอักษรที่เท่ากัน:

  • 0 และ 1 ไม่ถูกต้อง
  • 2 การแข่งขัน [abc]
  • จับคู่ 3 [def]
  • 4 แมตช์ [ghi]
  • 5 แมตช์ [jkl]
  • 6 แมตช์ [mno]
  • 7 แมตช์ [pqrs]
  • 8 แมตช์ [tuv]
  • และ 9 แมตช์ [wxyz]

ตัวอย่าง:

f('52726')
//returns ["Japan","japan","Japanee","Japanese","Japanesque"...,"larbowlines"]

f('552')
//returns ["Kjeldahl","kjeldahlization","kjeldahlize"...,"Lleu","Llew"]

f('1234')
//makes demons fly out your nose or divide by 0

f('9999')
//returns ["Zyzzogeton"]

f('999999')
//returns [] or null/nil or 0

หลังจากที่คุณใช้งานฟังก์ชั่นของคุณคุณสามารถพิมพ์ได้ทุกอย่างที่คุณต้องการ

กฎ:

  • ช่องโหว่มาตรฐานไม่ถูกต้อง
  • คุณต้องส่งคืนบางสิ่งแม้ว่ามันจะเป็นnull/ nil
    Javascript จะกลับมาundefinedถ้าคุณไม่คืนสิ่งใดดังนั้นกฎนี้
  • คุณไม่สามารถใช้หรือนำคำตอบของผู้อื่นมาใช้ซ้ำหรือคัดลอกการนำไปใช้ของฉัน
  • คุณสามารถสันนิษฐานได้ว่าสำหรับ Javascript นั้นเบราว์เซอร์จะเปิดขึ้นแล้วและinnerText/ / textContentขององค์ประกอบอัตโนมัติจะถูกส่งผ่านเป็นพารามิเตอร์ตัวที่ 2
  • สำหรับภาษาที่รวบรวมคุณไม่สามารถส่งผ่านอาร์กิวเมนต์พิเศษไปยังคอมไพเลอร์
  • คุณสามารถรับชื่อไฟล์ผ่านข้อโต้แย้งของคอมไพเลอร์
  • ตัวแปรมาโครตัวแปรโกลบอลค่าคงที่คลาสที่ไม่ได้มาตรฐานและการเรียงลำดับทั้งหมดที่ส่งผ่านค่าอื่น ๆ ภายในฟังก์ชั่นจะถือว่าไม่ถูกต้อง
  • ใน Javascript ตัวแปรที่ไม่มีคำหลักvarทำให้รหัสของคุณไม่ถูกต้อง
  • ฟังก์ชั่นของคุณจะถูกตั้งชื่อ f
  • คุณสามารถมีได้เพียง 2 ข้อโต้แย้งในฟังก์ชั่นของคุณ
  • พยายามที่จะทำให้รหัสของคุณภายใต้ 500 วินาทีในการทำงาน
  • คุณไม่ต้องกังวลกับช่องว่าง
  • คุณต้องใช้อักขระที่พิมพ์ได้ASCIIเท่านั้น
    จะมีการยกเว้นภาษาที่เพียงใช้ตัวอักษรที่ไม่พิมพ์ (APL และช่องว่าง 2 ตัวอย่าง)

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

  • จำนวนไบต์ต่ำสุดชนะ
  • มีที่ไม่ถูกต้องASCIIตัวอักษรพิมพ์ในคำตอบของคุณจะนับเป็นคำตอบที่ถูกเข้ารหัสในUTF-32
    ข้อยกเว้นการเข้ารหัสที่จะทำให้คำตอบของคุณจะนับจากตัวอักษร
  • เฉพาะส่วนของฟังก์ชั่นการนับเท่านั้นอย่านับสิ่งอื่นใดที่คุณทำภายนอก
  • โบนัส -30% ถ้าคุณสร้างระบบการทำนายตามคำที่คุ้นเคยหรือคำที่พบบ่อยที่สุด
  • โบนัสขนาด -20% หากคุณส่งคืนการแข่งขัน 5 ครั้งแรกสำหรับจดหมายแต่ละฉบับที่ตรงกับหมายเลขแรกเท่านั้น (เช่น: 245 จะส่งคืน 5 คำที่เริ่มต้นด้วย 'a', 5 เริ่มต้นด้วย 'b' และ 5 เริ่มต้นด้วย 'c' )

นี่คือตัวอย่างของการใช้งานโดยใช้ Javascript:

function f(phone, words)
{
    var keypad=['','','abc','def','ghi','jkl','mno','pqrs','tuv','wxyz'];
    var regex='';

    for(var i=0,l=phone.length;i<l;i++)
    {
        regex+='['+keypad[phone[i]]+']';
    }

    var regexp=new RegExp('\\s('+regex+'[a-z]*)\\s','gi');

    return words.match(regexp);
}

หากต้องการเรียกใช้ให้เปิดลิงก์รายการและเรียกใช้ตัวอย่างเช่น:

f('9999',document.getElementsByTagName('pre')[0].innerText);
//returns [" Zyzzogeton "]

ตัวอย่างนี้ทดสอบและทำงานภายใต้ Opera 12.17 64bits บน Windows 7 Home Edition 64bits


อาร์กิวเมนต์ที่สองของโปรแกรมเป็นชื่อไฟล์ที่มีคำหรือรายการคำศัพท์หรือไม่?
เครื่องมือเพิ่มประสิทธิภาพ

@ MartinBüttner UTF-8 ไม่ยุติธรรม (มันยังคงนับ ASCII chars ว่าเป็น 1 ไบต์) แต่ฉันเปลี่ยนกฎ
Ismael Miguel

@Optimizer อาร์กิวเมนต์ที่ 2 คือรายการคำศัพท์ คุณสามารถส่งชื่อไฟล์ไปยังอาร์กิวเมนต์คอมไพเลอร์และอ่านไฟล์ได้หากคุณต้องการ แต่สิ่งเดียวที่นับได้ก็คือร่างกายของฟังก์ชั่น
Ismael Miguel

@ MartinBüttnerการนับเป็น ASCII จะถูกนับเป็นไบต์ คุณต้องการให้ฉันบอกว่ารหัส APL จะมี 1 ไบต์มีขนาด 8 บิตหรือไม่
Ismael Miguel

2
-1 สำหรับข้อ จำกัด ที่ไม่เหมาะสม
AJMansfield

คำตอบ:


3

CJam, 28 ไบต์

q~{el{'h-_9/-D+3/}%s1$#!},p;

รับอินพุตในรูปแบบของ "<number>" [<list of words>]

ตัวอย่าง:

"52726" ["Japan" "japan" "Japanee" "Japanese" "Japanesque" "larbowlines" "ablution" "ablutionary" "abluvion" "ably" "abmho" "Abnaki" "abnegate"]

เอาท์พุท:

["Japan" "japan" "Japanee" "Japanese" "Japanesque" "larbowlines"]

จะไม่ได้รับโบนัสใด ๆ ในตอนนี้

ลองรหัสออนไลน์ที่นี่แต่สำหรับการวัดเวลาจริงเรียกใช้บนคอมไพเลอร์ Java

โปรดทราบว่า CJam แสดงรายการที่ว่างเปล่าเช่น ""

ในการแปลง wordlist แบบ raw ให้เป็นรายการ CJam ให้ใช้โค้ดต่อไปนี้กับ wordlist เป็นอินพุต:

qN/p

"คุณจะได้รับหมายเลขโทรศัพท์ 1 หมายเลขในสตริงและเนื้อหาของไฟล์ข้อความที่มีรายการคำศัพท์" -> คุณสามารถนำไปใช้กับบล็อกอื่นรหัสที่จำเป็นในการอ่านไฟล์ลงในรายการที่ใช้ได้หรือไม่
Ismael Miguel

@IsmaelMiguel คุณหมายถึงไม่ได้เป็นส่วนหนึ่งของรหัสนี้ แต่เพียงแค่รหัสผู้ช่วยในการแปลงรายการให้เป็นรูปแบบที่ถูกต้อง?
เครื่องมือเพิ่มประสิทธิภาพ

เผง รหัสของคุณไม่เพียงพอที่จะพิสูจน์ว่าสามารถใช้รายการคำเป็นตัวอย่างที่มีให้ แต่ฉัน upvoted ต่อไปฉันแค่ต้องการรหัสผู้ช่วยที่
Ismael Miguel

คุณสามารถเพิ่มลงในคำตอบได้หรือไม่? เป็นการแก้ไขในส่วนอื่น
Ismael Miguel

เผง นั่นคือสิ่งที่ฉันพูดถึง! ให้ดูว่าคุณสามารถปรับให้เหมาะสมยิ่งขึ้นไปอีกหรือไม่
Ismael Miguel

2

Java: 395

รูปแบบนี้เป็นรูปแบบ regex ตามตัวอักษรที่ได้รับอนุญาตสำหรับแต่ละหมายเลขจากนั้น tacks ที่. * ท้ายเพื่อจับคู่อักขระต่อไปนี้

นี่คือเวอร์ชั่น golfed:

static ArrayList<String> f(String n,ArrayList<String> d){String[] k={"","","([A-Ca-c])","([D-Fd-f])","([G-Ig-i])","([J-Lj-l])","([M-Om-o])","([P-Sp-s])","([T-Vt-v])","([W-Zw-z])"};String r="";for(int i=0;i<n.length();++i)r+=k[n.charAt(i)-'0'];r += ".*";Pattern p=Pattern.compile(r);ArrayList<String> a=new ArrayList<String>();for(String w:dictionary)if(p.matcher(w).matches())a.add(w);return a;}

และนี่คือเวอร์ชันที่ไม่ดีสำหรับความสามารถในการอ่าน

public static ArrayList<String> f(String phoneNumber, ArrayList<String> dictionary) {

    String[] KEY_VALUES = {"", "", "([A-Ca-c])", "([D-Fd-f])", "([G-Ig-i])",
                                            "([J-Lj-l])", "([M-Om-o])", "([P-Sp-s])",
                                            "([T-Vt-v])", "([W-Zw-z])"};

    String regex = "";
    for (int i = 0; i < phoneNumber.length(); ++i) {
        regex += KEY_VALUES[phoneNumber.charAt(i) - '0'];
    }
    regex += ".*";
    Pattern p = Pattern.compile(regex);
    ArrayList<String> answers = new ArrayList<String>();
    for (String word : dictionary) {
        if (p.matcher(word).matches()) {
            answers.add(word);
        }
    }
    return answers;
}

รหัสของคุณขัดแย้งกับกฎข้อ 7: "ตัวแปรแมโครตัวแปรส่วนกลางค่าคงที่คลาสที่ไม่ได้มาตรฐานและการเรียงลำดับทั้งหมดที่ส่งผ่านค่าอื่น ๆ ภายในฟังก์ชันจะถือว่าไม่ถูกต้อง" และมันก็ขัดกับกฎข้อที่ 3: "คุณไม่สามารถใช้หรือนำคำตอบของคนอื่นมาใช้ซ้ำหรือคัดลอกการนำไปใช้ของฉัน" แต่ในรหัสของคุณมันเป็นปัญหาที่เกิดขึ้น และยังขัดกับกฎที่ 9: "ฟังก์ชั่นของคุณจะถูกตั้งชื่อf"
Ismael Miguel

@IsmaelMiguel โอ๊ะโอ กฎข้อที่ 7 สามารถแก้ไขได้อย่างง่ายดายโดยการย้ายค่าคงที่ภายในฟังก์ชั่น ฉันแค่ดึงมันออกมานอกฟังก์ชั่นเพื่อสไตล์การเขียนโปรแกรมที่ดีขึ้น กฎข้อที่ 9 ยังแก้ไขได้ง่าย ฉันยอมรับว่าไม่ได้อ่านคำตอบของคุณดังนั้นฉันจึงไม่ได้ตั้งใจคัดลอก ฉันสามารถลบคำตอบถ้าคุณคิดว่ามันใกล้เกินไปสำหรับการแข่งขัน
Brian J

คำตอบของคุณไม่เป็นไร คุณมีข้อบกพร่องในรหัสของคุณ บนอย่างต่อเนื่องที่ผ่านมา ( ([W-Zw-z)]) ([W-Zw-z])มันควรจะเป็น และใน Code-golf คุณไม่ต้องกังวลเกี่ยวกับรูปแบบการเขียนโปรแกรมและแนวปฏิบัติที่ดี: รหัสของคุณจะต้องเป็นสิ่งที่จำเป็นต้องมีพารามิเตอร์ที่จำเป็น $s=[2=>abc,def,ghi,jkl,mno,pqrs,tuv,wxyz];หากคุณตรวจสอบคำตอบของฉันคุณจะเห็นบรรทัดนี้ นี่เป็น 'อาชญากรรม' ที่น่ากลัวใน PHP โดยทั่วไปฉันบังคับให้ PHP แปลงค่าคงที่ที่ไม่มีอยู่เป็นสตริง นี่เป็นที่ยอมรับอย่างสมบูรณ์ คุณจะเห็นว่าฉันไม่ได้ตั้งค่าตัวแปร$tเป็นอาร์เรย์ก่อนที่จะใช้มันเช่นนี้
Ismael Miguel

@IsmaelMiguel เข้าใจดีเกี่ยวกับข้อผิดพลาด regex ขอบคุณที่ชี้นำ ฉันจะพยายามเล่นกอล์ฟวันพรุ่งนี้ อาจพบตัวอย่าง Java บนเว็บไซต์นี้
Brian J

ฉันไม่ใช่โปรแกรมเมอร์ Java แต่ฉันบอกคุณบางอย่าง คุณสามารถตรวจสอบcodegolf.stackexchange.com/questions/6671/…เพื่อรับคำแนะนำได้ เคล็ดลับทั่วไปรวมถึงการลบช่องว่างที่ไม่มีประโยชน์ (บรรทัดใหม่ช่องว่างแท็บ) ชื่อตัวแปรที่มีความยาวหนึ่งตัวอักษรและทำทุกอย่างที่คุณสามารถทำได้เพื่อลดขนาดรหัสให้มากที่สุด
Ismael Miguel

1

C # .NET 4.5 235

สิ่งนี้น่าจะใช้ได้:

IEnumerable<string>F(string n,string d){IEnumerable<string>w=d.Split(null).ToList();string[]a={"","","abc","def","ghi", "jkl","mno","pqrs","tuv","wxyz"};foreach(var i in n){w=w.Where(x=>x.IndexOfAny(a[i-'0'].ToArray())>0);}return w;}

ยินดีต้อนรับสู่ PPCG รหัสของคุณจะใช้งานได้ แต่คุณยังต้องลดให้มากขึ้น โดยการลบช่องว่างที่ไร้ประโยชน์ทั้งหมด (ช่องว่างแท็บบรรทัดใหม่) ฉันมีการจัดการเพื่อลดรหัสของคุณถึง 167 ไบต์ รหัสนี้สามารถลดได้มากขึ้นฉันแน่ใจ ฉันแนะนำให้อ่านcodegolf.stackexchange.com/questions/173/…เพื่อย่อรหัสของคุณให้สั้นลง เพื่อช่วยให้คุณเล็กน้อยรายการคำเป็นสตริงคั่นด้วยการขึ้นบรรทัดใหม่และคุณคิดว่าเป็นไปได้ที่จะใช้foreachใน หากคุณคาดหวังว่าจะเป็นIEnumerableเช่นนั้นให้ใส่รหัสที่ใช้ภายนอก
Ismael Miguel

@IsmaelMiguel TY ฉันจะดูมัน รายการนั้นเป็น IEnumerable ไม่มีรหัสนอกสิ่งที่ฉันโพสต์
Chaossie

หากคุณดูข้อมูลจำเพาะของฟังก์ชั่นคุณจะเห็นพารามิเตอร์ที่ 2 เป็นสตริง (Quoting: "คุณจะได้รับ 1 หมายเลขโทรศัพท์ในสายอักขระและเนื้อหาของไฟล์ข้อความที่มีรายการคำ (ไม่ต้องใช้สไตล์บรรทัดใหม่เฉพาะเจาะจง") และคุณมีช่องว่างที่ไม่มีประโยชน์ 1 aรายการ
Ismael Miguel

ฉันสังเกตเห็นการปรับปรุงในคำถามของคุณและฉันให้ upvote แต่คุณยังสามารถบันทึกไบต์บนavar ของคุณ แต่ฉันเห็นการปรับปรุงที่เห็นได้ชัดเจนจริงๆ! ดีแล้วทำต่อไป.
Ismael Miguel

1

Python 2 (155 ไบต์)

ควรทำงานใน Python 3 ด้วยการแทนที่ที่เหมาะสม ( string-> bytes, bคำนำหน้าบนสตริง ฯลฯ )

ฉันไม่แน่ใจว่าการmaketransโทรออกนอกฟังก์ชั่นนั้นถือว่าเป็น "ยุติธรรม" หรือไม่ ถ้าไม่ฟังก์ชั่นคือ 134 ไบต์โดยที่มันย้ายไปข้างใน

แก้ไข:วางหนึ่งไบต์จากการกำกับดูแลที่โง่

เมื่อเตรียมmaketransแล้ว 67 ไบต์:

from string import maketrans
t=maketrans('abcdefghijklmnopqrstuvwxyz','22233344455566677778889999')

def f(n,w):
    return[x for x in w.split()if x.lower().translate(t).startswith(n)]

ด้วยmaketransในร่างกาย 134 ไบต์:

from string import maketrans

def f(n,w):
    return[x for x in w.split()if x.lower().translate(maketrans('abcdefghijklmnopqrstuvwxyz','22233344455566677778889999')).startswith(n)]

ด้วยimportและmaketransในร่างกาย 155 ไบต์:

def f(n,w):
    return[x for x in w.split()if x.lower().translate(__import__('string').maketrans('abcdefghijklmnopqrstuvwxyz','22233344455566677778889999')).startswith(n)]

ทดสอบการโทร:

print f('9999',open('words.txt','rt').read())

maketransเป็นส่วนหนึ่งของร่างกายของฟังก์ชั่น คุณควรย้ายมัน ผมไม่ทราบว่ามันเป็นไปได้ importแต่คุณสามารถพยายามที่จะใช้โดยตรง ฉันคิดว่าฉันเห็นมันอยู่ที่ไหนสักแห่ง ... แต่รหัสของคุณดีจริงๆ!
Ismael Miguel

คุณหมายถึงการย้ายการนำเข้าและการโทรเข้าสู่ร่างกายหรือไม่? ใช่ฉันคิดว่าสามารถทำได้เช่นกัน
criptych ย่อมาจาก Monica

t=(from stirng import maketrans)([...])ฉันคิดเกี่ยวกับ ฉันไม่รู้ว่ามันจะเป็นไปได้ไหม แต่บางทีคุณสามารถใช้from string import as x t=x([...])ที่ฉันไม่แน่ใจว่าเป็นไปได้เช่นกัน: /
Ismael Miguel

รุ่นที่ถูกต้องเป็นรุ่นสุดท้าย แต่คำตอบก็เป็นที่ยอมรับในความคิดของฉัน +1 __import__('string').maketranสำหรับ
Ismael Miguel

โอเคขอบคุณ. ฉันลบคำตอบที่ไม่ถูกต้องออกแล้ว
criptych ย่อมาจาก Monica

0

PHP 5.4+ (171 186-20% = 148.8 ไบต์):

นี่เป็นคำตอบที่ค่อนข้างใหญ่ แต่ก็ดี

ฉันหวังว่านี่จะทำให้ผู้คนตอบรับมากขึ้น

ฟังก์ชั่นนี้คาดว่าจะมีการอ่านเนื้อหาดิบ

นี่คือรหัส:

function f($_,$a){$s=[2=>abc,def,ghi,jkl,mno,pqrs,tuv,wxyz];$a=preg_split('@\r\n|\r|\n@',$a);for($i=0;$c=$_[$i];++$i)foreach($a as$k=>$v)if(!strpos(1..$s[$c],$v[$i])||$t[$v[0]]++>4)unset($a[$k]);return$a;}

สิ่งนี้ทำงานโดยตรวจสอบว่าตัวอักษรนั้นอยู่ในรายการของตัวอักษรที่อนุญาต

ตัวอย่าง: การป้อนข้อมูล36จะทำการตรวจสอบว่า1abcมีตัวอักษรตัวแรกของคำและที่1defมีตัวอักษรที่สอง

ฉันผนวก1ดังนั้นมันจึงไม่ตรวจสอบว่าจดหมายอยู่ในตำแหน่งที่ 1 (ซึ่งจะกลับมา0และจะประเมินให้false) if(!strpos(1..$s[$c],$v[$i]))หรือif(!strpos($c.$s[$c],$v[$i]))จะมีผลเหมือนกัน แต่ที่ 1 สับสนมากขึ้นและฉันชอบมัน

หากไม่สามารถทำได้จะลบคำนั้นออก

หากไม่มีคำเหลือจะส่งคืนอาร์เรย์ว่าง

หากต้องการทดสอบออนไลน์นี้ไปที่http://writecodeonline.com/php/และสร้างตัวแปรอย่างง่ายพร้อมคำสำหรับบรรทัด

ตัวอย่างที่ทดสอบได้:

function f($_,$a)
{
    $s=array(2=>abc,def,ghi,jkl,mno,pqrs,tuv,wxyz);
    $a=preg_split('@\r\n|\r|\n@',$a);

    for($i=0;$c=$_[$i];++$i)
        foreach($a as$k=>$v)
            if(!strpos(1..$s[$c],$v[$i]) || $t[$v[0]]++>4)
                unset($a[$k]);
    return$a;
}

$lines=<<<WORDS
one
two
three
four
five
six
seven
eight
nine
ten
WORDS;

var_dump(f('36',$lines));

ผลลัพธ์นี้ควร:

array(1) {
    [3]=>
      string(4) "four"
}

ในการทำงานกับเวอร์ชั่นเก่าของ PHP ให้แทนที่$s=[2=>abc,def,ghi,jkl,mno,pqrs,tuv,wxyz];ด้วย$s=array(2=>abc,def,ghi,jkl,mno,pqrs,tuv,wxyz);


สำหรับโบนัส 20%:

เพื่อลดรหัสฉันเพิ่งเพิ่ม||$t[$v[0]]++>4ซึ่งตรวจสอบกี่ครั้งที่ใช้ตัวอักษรตัวแรก

ใน php $tไม่จำเป็นต้องมีการกำหนดช่วยลดก้อนใหญ่37.2ไบต์

ในการดูเอฟเฟกต์นี้ให้ใช้ตัวแปรต่อไปนี้เป็นอาร์กิวเมนต์ที่ 2:

$lines=<<<WORDS
one
two
three
four
five
six
seven
eight
nine
ten
twelve
time
tutor
test
truth
WORDS;
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.