1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use super::ContextInformation;
use super::{Frac, Plan, StepResult};
#[derive(Debug, PartialEq, Clone)]
pub(super) struct Base256Plan<T: ContextInformation> {
ctx: T,
written: usize,
cost: Frac,
}
impl<T: ContextInformation> Base256Plan<T> {
pub(super) fn with_written(mut ctx: T, written: usize) -> Self {
let cost = if written == 0 {
ctx.write(1);
1
} else {
0
};
Self {
ctx,
written,
cost: cost.into(),
}
}
pub(super) fn new(ctx: T) -> Self {
Self::with_written(ctx, 0)
}
pub(super) fn context(&self) -> &T {
&self.ctx
}
}
impl<T: ContextInformation> Plan for Base256Plan<T> {
type Context = T;
fn mode_switch_cost(&self) -> Option<Frac> {
if self.written >= 250 {
Some(self.cost + 1)
} else {
Some(self.cost)
}
}
fn cost(&self) -> Frac {
if !self.ctx.has_more_characters() {
let left = self.ctx.symbol_size_left(0).unwrap_or(1);
if left > 0 && self.written > 249 {
return self.cost + 1;
}
}
self.cost
}
fn write_unlatch(&self) -> T {
let mut ctx = self.ctx.clone();
if self.written >= 250 {
ctx.write(1);
}
ctx
}
fn step(&mut self) -> Option<StepResult> {
let end = !self.ctx.has_more_characters();
if !end {
let _ = self.ctx.eat().unwrap();
self.written += 1;
self.cost += 1;
self.ctx.write(1);
if self.written == 1556 {
return None;
}
}
Some(StepResult {
end,
unbeatable: false,
})
}
}