งาน
ใช้โปรแกรมอย่างน้อยไบต์ของซอร์สโค้ดหรือรหัสไบนารี่ที่ทำการรู้จำเสียงของตัวอย่างเสียง (ฉันพูดว่า "ใช่", "ใช่" หรือ "ไม่" ในเสียงหรือกระซิบชัดแจ้งหรือเล่นโวหาร) ตามตัวอย่างการฝึกอบรมที่มีความแม่นยำสูงสุด .
โปรแกรมที่ควรอ่านtrain/yes0.wav
, train/no0.wav
, train/yes1.wav
และอื่น ๆ (มี 400 yeses และ 400 noes ในชุดฝึกอบรม) แล้วเริ่มต้นการอ่านinputs/0.wav
, inputs/1.wav
จนกว่าจะล้มเหลวในการค้นหาไฟล์, การวิเคราะห์และแสดงผลว่า "ใช่" หรือ "ไม่ใช่" (หรือคำอื่น ๆ สำหรับ คำตอบระดับกลาง)
หากคุณต้องการคุณสามารถฝึกฝนโปรแกรมล่วงหน้าแทนการอ่านtrain/
แต่ตารางข้อมูลผลลัพธ์จะนับรวมคะแนน (และระวังการ overfitting ตัวอย่างการฝึกอบรม - พวกเขาไม่ทับซ้อนกับการตรวจสอบ) ดีกว่าที่จะรวมโปรแกรมที่ใช้สร้างตารางข้อมูลเป็นภาคผนวกในกรณีนี้
ไฟล์ตัวอย่างทั้งหมดเป็นไฟล์ WAV สเตอริโอ 16 บิตแบบ endian เพียงเล็กน้อยจากแล็ปท็อปไมค์โดยไม่ต้องกรอง / ลดเสียงรบกวน
ขีด จำกัด
คุณสมบัติต้องห้าม:
- ใช้เครือข่าย
- พยายามที่จะเข้าถึงแฟ้มคำตอบ
inputs/key
; - การทำลาย
runner
โปรแกรมที่คำนวณความแม่นยำ - การใช้ไลบรารีการจดจำที่มีอยู่ ไม่อนุญาตให้เชื่อมโยงไปยังการใช้ FFT: อนุญาตให้ใช้ฟังก์ชันคณิตศาสตร์ภายนอกที่รับข้อมูลจำนวนคงที่ (เช่น
sin
หรือatan2
) เท่านั้น หากคุณต้องการ FFT เพียงเพิ่มการติดตั้งไปยังซอร์สโค้ดโปรแกรมของคุณ (สามารถพูดได้หลายภาษาหากจำเป็น)
ข้อ จำกัด ทรัพยากร:
- โปรแกรมไม่ควรใช้เวลา CPU มากกว่า 30 นาทีบนแล็ปท็อป i5 ของฉัน หากใช้เวลามากกว่าจะนับเฉพาะผลผลิตที่ผลิตใน 30 นาทีแรกเท่านั้นและจะมีการนับอีกครึ่งหนึ่ง
- จำกัด หน่วยความจำ: 1GB (รวมถึงไฟล์ชั่วคราว);
เครื่องมือ
tools/runner
โปรแกรมจะทำงานโดยอัตโนมัติวิธีการแก้ปัญหาของคุณและคำนวณความถูกต้อง
$ tools/runner solutions/example train train/key
Accuracy: 548 ‰
สามารถตรวจสอบโปรแกรมโดยใช้ข้อมูลการฝึกอบรมหรือใช้ข้อมูลการสอบจริง ฉันจะลองส่งคำตอบเกี่ยวกับชุดข้อมูลการตรวจสอบและเผยแพร่ผลลัพธ์ (เปอร์เซ็นต์ความแม่นยำ) จนกว่าฉันจะเผยแพร่ชุดข้อมูลให้เป็นสาธารณะ
เกณฑ์การให้คะแนน
โซลูชันมี 5 ระดับขึ้นอยู่กับความถูกต้อง:
- ตัวอย่างทั้งหมดเดาอย่างถูกต้อง: คลาส 0;
- ความแม่นยำ 950-999: รุ่นที่ 1;
- ความแม่นยำ 835-950: Class 2;
- ความแม่นยำ 720-834: รุ่นที่ 3;
- ความแม่นยำ 615-719: Class 4;
ภายในแต่ละชั้นเรียนคะแนนคือจำนวนไบต์ที่ใช้ในการแก้ปัญหา
คำตอบที่ได้รับการยอมรับ: ทางออกที่เล็กที่สุดในชั้นเรียนที่ไม่ว่างเปล่าที่ดีที่สุด
การเชื่อมโยง
- โครงการ Github ด้วยเครื่องมือ: https://github.com/vi/codegolf-jein
- ชุดข้อมูลการฝึกอบรม: http://vi-server.org/pub/codegolf-jein-train.tar.xz
- ชุดข้อมูลการตรวจสอบจะถูกเก็บเป็นส่วนตัวจนถึงขณะนี้ยังมี checksums (HMAC) ในที่เก็บ Github
ตัวอย่างทั้งหมดควรพิจารณา CC-0 (โดเมนสาธารณะ) สคริปต์และโปรแกรมควรพิจารณา MIT
ตัวอย่างการแก้ปัญหา
มันให้คุณภาพการรับรู้ที่ต่ำมากเพียงแค่แสดงวิธีอ่านไฟล์และคำตอบเอาต์พุต
#define _BSD_SOURCE
#include <stdio.h>
#include <assert.h>
#include <endian.h>
#define Nvols 30
#define BASS_WINDOW 60
#define MID_WINDOW 4
struct training_info {
double bass_volumes[Nvols];
double mid_volumes[Nvols];
double treble_volumes[Nvols];
int n;
};
struct training_info yes;
struct training_info no;
static int __attribute__((const)) mod(int n, int d) {
int m = n % d;
if (m < 0) m+=d;
return m;
}
// harccoded to 2 channel s16le
int get_file_info(const char* name, struct training_info *inf) {
FILE* in = fopen(name, "rb");
if (!in) return -1;
setvbuf(in, NULL, _IOFBF, 65536);
inf->n = 1;
fseek(in, 0, SEEK_END);
long filesize = ftell(in);
fseek(in, 128, SEEK_SET);
filesize -= 128; // exclude header and some initial samples
int nsamples = filesize / 4;
double bass_a=0, mid_a=0;
const int HISTSIZE = 101;
double xhistory[HISTSIZE];
int histpointer=0;
int histsize = 0;
//FILE* out = fopen("debug.raw", "wb");
int i;
for (i=0; i<Nvols; ++i) {
int j;
double total_vol = 0;
double bass_vol = 0;
double mid_vol = 0;
double treble_vol = 0;
for (j=0; j<nsamples / Nvols; ++j) {
signed short int l, r; // a sample
if(fread(&l, 2, 1, in)!=1) break;
if(fread(&r, 2, 1, in)!=1) break;
double x = 1/65536.0 * ( le16toh(l) + le16toh(r) );
bass_a += x;
mid_a += x;
if (histsize == HISTSIZE-1) bass_a -= xhistory[mod(histpointer-BASS_WINDOW,HISTSIZE)];
if (histsize == HISTSIZE-1) mid_a -= xhistory[mod(histpointer-MID_WINDOW ,HISTSIZE)];
double bass = bass_a / BASS_WINDOW;
double mid = mid_a / MID_WINDOW - bass;
double treble = x - mid_a/MID_WINDOW;
xhistory[histpointer++] = x;
if(histpointer>=HISTSIZE) histpointer=0;
if(histsize < HISTSIZE-1) ++histsize;
total_vol += bass*bass + mid*mid + treble*treble;
bass_vol += bass*bass;
mid_vol += mid*mid;
treble_vol += treble*treble;
/*
signed short int y;
y = 65536 * bass;
y = htole16(y);
fwrite(&y, 2, 1, out);
fwrite(&y, 2, 1, out);
*/
}
inf->bass_volumes[i] = bass_vol / total_vol;
inf->mid_volumes[i] = mid_vol / total_vol;
inf->treble_volumes[i] = treble_vol / total_vol;
//fprintf(stderr, "%lf %lf %lf %s\n", inf->bass_volumes[i], inf->mid_volumes[i], inf->treble_volumes[i], name);
}
fclose(in);
return 0;
}
static void zerotrdata(struct training_info *inf) {
int i;
inf->n = 0;
for (i=0; i<Nvols; ++i) {
inf->bass_volumes[i] = 0;
inf->mid_volumes[i] = 0;
inf->treble_volumes[i] = 0;
}
}
static void train1(const char* prefix, struct training_info *inf)
{
char buf[50];
int i;
for(i=0;; ++i) {
sprintf(buf, "%s%d.wav", prefix, i);
struct training_info ti;
if(get_file_info(buf, &ti)) break;
++inf->n;
int j;
for (j=0; j<Nvols; ++j) {
inf->bass_volumes[j] += ti.bass_volumes[j];
inf->mid_volumes[j] += ti.mid_volumes[j];
inf->treble_volumes[j] += ti.treble_volumes[j];
}
}
int j;
for (j=0; j<Nvols; ++j) {
inf->bass_volumes[j] /= inf->n;
inf->mid_volumes[j] /= inf->n;
inf->treble_volumes[j] /= inf->n;
}
}
static void print_part(struct training_info *inf, FILE* f) {
fprintf(f, "%d\n", inf->n);
int j;
for (j=0; j<Nvols; ++j) {
fprintf(f, "%lf %lf %lf\n", inf->bass_volumes[j], inf->mid_volumes[j], inf->treble_volumes[j]);
}
}
static void train() {
zerotrdata(&yes);
zerotrdata(&no);
fprintf(stderr, "Training...\n");
train1("train/yes", &yes);
train1("train/no", &no);
fprintf(stderr, "Training completed.\n");
//print_part(&yes, stderr);
//print_part(&no, stderr);
int j;
for (j=0; j<Nvols; ++j) {
if (yes.bass_volumes[j] > no.bass_volumes[j]) { yes.bass_volumes[j] = 1; no.bass_volumes[j] = 0; }
if (yes.mid_volumes[j] > no.mid_volumes[j]) { yes.mid_volumes[j] = 1; no.mid_volumes[j] = 0; }
if (yes.treble_volumes[j] > no.treble_volumes[j]) { yes.treble_volumes[j] = 1; no.treble_volumes[j] = 0; }
}
}
double delta(struct training_info *t1, struct training_info *t2) {
int j;
double d = 0;
for (j=0; j<Nvols; ++j) {
double rb = t1->bass_volumes[j] - t2->bass_volumes[j];
double rm = t1->mid_volumes[j] - t2->mid_volumes[j];
double rt = t1->treble_volumes[j] - t2->treble_volumes[j];
d += rb*rb + rm*rm + rt*rt;
}
return d;
}
int main(int argc, char* argv[])
{
(void)argc; (void)argv;
train();
int i;
int yes_count = 0;
int no_count = 0;
for (i=0;; ++i) {
char buf[60];
sprintf(buf, "inputs/%d.wav", i);
struct training_info ti;
if(get_file_info(buf, &ti)) break;
double dyes = delta(&yes, &ti);
double dno = delta(&no, &ti);
//printf("%lf %lf %s ", dyes, dno, buf);
if (dyes > dno) {
printf("no\n");
++no_count;
} else {
printf("yes\n");
++yes_count;
}
}
fprintf(stderr, "yeses: %d noes: %d\n", yes_count, no_count);
}
sum
หรือเราจำเป็นต้องใช้foldl (+) 0
(foldl ไม่ใช่คณิตศาสตร์เฉพาะและ+
ไม่แปรปรวน)?
sum
คุณได้อย่างมีประสิทธิภาพห้าม ฉันเดาว่านั่นไม่ใช่ความตั้งใจของคุณ?