Skip to content

Commit e4871d3

Browse files
Initial
0 parents  commit e4871d3

File tree

9 files changed

+116
-0
lines changed

9 files changed

+116
-0
lines changed

.idea/.gitignore

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/task1.iml

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module task1
2+
3+
go 1.21
4+
5+
require golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg=
2+
golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=

main.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package main
2+
3+
import (
4+
"errors"
5+
"fmt"
6+
"golang.org/x/exp/mmap"
7+
"math/big"
8+
)
9+
10+
// f is the Fibonacci cache table, it values found by fib() func
11+
var f = []*big.Int{big.NewInt(0), big.NewInt(1)}
12+
13+
// maxFib stores n of maximum fibonacci number found
14+
var maxFib uint64 = 2
15+
16+
// Using big math because maximum Fibonacci number that can be returned for int64 is
17+
// F(93) = 12,200,160,415,121,876,738
18+
19+
// fib calculates Fibonacci number using big math.
20+
func fib(n uint64) *big.Int {
21+
// Updating fibonacci table up to the needed number, if it is not already cached
22+
for ; maxFib <= n; maxFib++ {
23+
c := big.Int{}
24+
f = append(f, c.Add(f[maxFib-1], f[maxFib-2]))
25+
}
26+
return f[n]
27+
}
28+
29+
// getPossibleCombinations calculates # of possible ways to decode the message
30+
func getPossibleCombinations(p []byte) (*big.Int, error) {
31+
clusterSize := uint64(0)
32+
x := big.NewInt(1)
33+
a := p[0]
34+
// If string starts with 0 or not digit, return 0
35+
if a == 0x30 {
36+
return big.NewInt(0), errors.New("string starts with 0")
37+
} else if a < 0x31 || a > 0x39 {
38+
return big.NewInt(0), errors.New("string starts with non-digit character")
39+
}
40+
for i, b := range p[1:] {
41+
// If there is non-digit in the string, return 0
42+
if b < 0x30 || b > 0x39 {
43+
return big.NewInt(0), fmt.Errorf("encountered non-digit character at pos. %d", i)
44+
}
45+
// if next digit is 0, and value is not 10 or 20, return 0
46+
if b == 0x30 && a != 0x31 && a != 0x32 {
47+
return big.NewInt(0), fmt.Errorf("encountered 0 which can not be attached to %c at pos. %d", a, i)
48+
}
49+
// checking if value is in range 11-19, 21-26 (can be treated both like separate or single)
50+
if (a == 0x31 && b > 0x30) || (a == 0x32 && b > 0x30 && b <= 0x36) {
51+
// we are in a cluster
52+
clusterSize++
53+
} else if clusterSize > 0 {
54+
// exited from a cluster
55+
x.Mul(x, fib(clusterSize+2))
56+
clusterSize = 0
57+
}
58+
a = b
59+
}
60+
if clusterSize > 0 {
61+
// if the string ended on a cluster
62+
x.Mul(x, fib(clusterSize+2))
63+
}
64+
return x, nil
65+
}
66+
67+
func main() {
68+
r, err := mmap.Open("test2.txt")
69+
if err != nil {
70+
panic(err)
71+
}
72+
p := make([]byte, r.Len())
73+
if _, err = r.ReadAt(p, 0); err != nil {
74+
panic(err)
75+
}
76+
x, err := getPossibleCombinations(p)
77+
if err != nil {
78+
panic(err)
79+
}
80+
fmt.Print(x)
81+
}

test.res

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

test.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
10566211535152

test2.txt

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)