컬렉션과 문자열을 함께 쓴다. 구조체를 담는 제네릭 리스트, 슬라이스 비교, 처음 본 순서 유지, 그리고 할당과 해제가 맞는지 확인. the 3 / cat 2 / sat 1 / distinct 5 / balanced run.py 209/209, exec.py 21/21.
83 lines
2.2 KiB
Plaintext
83 lines
2.2 KiB
Plaintext
// EXIT:0
|
|
// OUTPUT:the 3
|
|
// OUTPUT:cat 2
|
|
// OUTPUT:sat 1
|
|
// OUTPUT:distinct 5
|
|
// OUTPUT:balanced
|
|
unit wordfreq;
|
|
import std.io;
|
|
import std.fmt;
|
|
import std.str;
|
|
import std.list;
|
|
import std.sys;
|
|
|
|
// Count how often each word appears, in the order the words were first seen.
|
|
// A word is a run of anything that is not a space.
|
|
|
|
struct Word {
|
|
from: usize,
|
|
len: usize,
|
|
count: i32,
|
|
}
|
|
|
|
fn report(text: []u8, w: Word) -> void {
|
|
var buf: [16]u8 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
|
|
let n: usize = fmt.fmt_i32(buf[..], w.count);
|
|
io.print(text[w.from..w.from + w.len]);
|
|
io.print(" ");
|
|
io.print(buf[0..n]);
|
|
io.print("\n");
|
|
}
|
|
|
|
fn tally(text: []u8) -> !i32 {
|
|
var words: list.List(Word) = try list.List(Word).with_capacity(4);
|
|
var at: usize = 0;
|
|
while at < text.n {
|
|
var stop: usize = at;
|
|
while stop < text.n {
|
|
if text[stop] == 32 { break; }
|
|
stop = stop + 1;
|
|
}
|
|
if stop > at {
|
|
let word: []u8 = text[at..stop];
|
|
var seen: bool = false;
|
|
var i: usize = 0;
|
|
while i < words.count() {
|
|
let known: Word = words.at(i);
|
|
if str.eq(text[known.from..known.from + known.len], word) {
|
|
words.set(i, Word{ from: known.from, len: known.len,
|
|
count: known.count + 1 });
|
|
seen = true;
|
|
break;
|
|
}
|
|
i = i + 1;
|
|
}
|
|
if not seen {
|
|
try words.push(Word{ from: at, len: stop - at, count: 1 });
|
|
}
|
|
}
|
|
at = stop + 1;
|
|
}
|
|
var k: usize = 0;
|
|
while k < words.count() {
|
|
let w: Word = words.at(k);
|
|
if w.count > 1 or k < 3 { report(text, w); }
|
|
k = k + 1;
|
|
}
|
|
return words.count() as i32;
|
|
}
|
|
|
|
fn main() -> i32 {
|
|
let distinct: i32 = tally("the cat sat on the mat the cat") catch |e| {
|
|
return 1;
|
|
};
|
|
var buf: [16]u8 = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
|
|
let n: usize = fmt.fmt_i32(buf[..], distinct);
|
|
io.print("distinct ");
|
|
io.print(buf[0..n]);
|
|
io.print("\n");
|
|
if sys.allocs() != sys.frees() { io.print("leaked\n"); return 2; }
|
|
io.print("balanced\n");
|
|
return 0;
|
|
}
|