This repository has been archived by the owner on May 13, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
110 lines (100 loc) Β· 1.89 KB
/
main.go
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package main
import (
"bufio"
"flag"
"fmt"
"io"
"os"
"strconv"
"strings"
)
var test = flag.Bool("test", false, "use test input")
var testCases = `4 4 0
0 4097
4096 8193
8192 12289
12288 16385
0
4096
42
131313
-
3 3 0
0 8193
8192 12289
12288 1
0
4096
42`
func main() {
var input io.Reader = os.Stdin
if flag.Parse(); *test {
input = strings.NewReader(testCases)
}
scan := bufio.NewScanner(input)
scan.Split(bufio.ScanWords)
for scan.Scan() {
var (
m, _ = strconv.Atoi(read(scan))
q, _ = strconv.Atoi(read(scan))
r, _ = strconv.Atoi(read(scan))
)
memory := make(map[uint64]uint64, m)
for i := 0; i < m; i++ {
paddr, _ := strconv.ParseUint(read(scan), 10, 64)
value, _ := strconv.ParseUint(read(scan), 10, 64)
memory[paddr] = value
}
logical := make([]uint64, 0, q)
for i := 0; i < q; i++ {
addr, _ := strconv.ParseUint(read(scan), 10, 64)
logical = append(logical, addr)
}
for i, addr := range logical {
pml4e, pdpte, pde, pte, offset := split(addr)
paddr := uint64(r)
for _, row := range []uint16{pml4e, pdpte, pde, pte} {
paddr += uint64(row * 8)
val, ok := memory[paddr]
if !ok {
paddr = 0
break
}
paddr, ok = chain(val)
if !ok {
paddr = 0
break
}
}
if paddr != 0 {
paddr += uint64(offset)
}
logical[i] = paddr
}
for _, addr := range logical {
if addr == 0 {
fmt.Println("fault")
continue
}
fmt.Println(addr)
}
}
}
func read(scan *bufio.Scanner) string {
defer scan.Scan()
return scan.Text()
}
func split(addr uint64) (pml4e, pdpte, pde, pte, offset uint16) {
pml4e = uint16((addr >> 39) & 511)
pdpte = uint16((addr >> 30) & 511)
pde = uint16((addr >> 21) & 511)
pte = uint16((addr >> 12) & 511)
offset = uint16(addr & 4095)
return
}
func chain(addr uint64) (naddr uint64, valid bool) {
if addr&1 == 1 {
return addr - 1, true
}
return 0, false
}