Index finite lists of positive integers: Difference between revisions

Content added Content deleted
m (fixed an HTML tag.)
(→‎{{header|Go}}: cleanups. handle empty list, return errors rather than panic, add output showing empty list and errors.)
Line 58:
)
 
// JoinPrepend base 10 representationsrepresentation with an "a" and you get a base 11 number.
// Unfortunately base 11 is a little awkward with big.Int, so just treat it as base 16.
// as base 16.
func rank(l []big.Int) *(r big.Int, err error) {
if len(l) == 0 {
if !ok {return
}
s := make([]string, len(l))
for i, n := range l {
s[i]ns := n.String()
if ns[0] == '-' {
}
return r, fmt.Errorf("negative integers not mapped")
i, ok := new(big.Int).SetString(strings.Join(s, "a"), 16)
if !ok { }
panic(s[i] = "huha") + ns
}
i, ok := new(big.Int)r.SetString(strings.Join(s, "a"), 16)
return i
}
 
// Split the base 16 representation at "a", recover the base 10 numbers.
func unrank(r *big.Int) ([]big.Int, error) {
ss16 := strings.Split(fmt.Sprintf("%x", &r), "a")
switch {
case s16 == "0":
return nil, nil // empty list
case s16[0] != 'a':
return nil, fmt.Errorf("unrank not bijective")
}
s := strings.Split(s16[1:], "a")
l := make([]big.Int, len(s))
for i, s1 := range s {
if _, ok := l[i].SetString(s1, 10); !ok {
return nil, fmt.Errorf("unrank not bijective")
if !ok {
panic("really")
}
}
return l, nil
}
 
func main() {
l// :=show random()empty list
var l []big.Int
fmt.Println("List:")
r, _ := rank(l)
u, _ := unrank(r)
fmt.Println("Empty list:", l, &r, u)
 
// show random list
l = random()
r, _ = rank(l)
u, _ = unrank(r)
fmt.Println("List\nList:")
for _, n := range l {
fmt.Println(" ", &n)
}
r := rank(l)
fmt.Println("Rank:")
fmt.Println(" ", &r)
u := unrank(r)
fmt.Println("Unranked:")
for _, n := range u {
fmt.Println(" ", &n)
}
 
// show error with list containing negative
var n big.Int
n.SetInt64(-5)
_, err := rank([]big.Int{n})
fmt.Println("\nList element:", &n, err)
 
// show technique is not bijective
n.SetInt64(1)
_, err = unrank(n)
fmt.Println("Rank:", &n, err)
}
 
// returns 30 to 105 numbers in the range 1 to 2^100
func random() []big.Int {
r := rand.New(rand.NewSource(time.Now().Unix()))
l := make([]big.Int, 3+r.Intn(86))
one := big.NewInt(1)
max := new(big.Int).Lsh(one, 100)
Line 114 ⟶ 143:
{{out}}
<pre>
Empty list: [] 0 []
 
List:
170245492534662309353778826165
250046378143152073779399139308
82227712638678862510272817700
433677733115839140356036818773
709681404405498840918712626000
Rank:
17827272030291729487097780664374477811820701746650470453292650775464474368
86898591846547743089837040293705765764160568618712035006919317223922729203294339688481288514295259746298650624
Unranked:
170245492534662309353778826165
250046378143152073779399139308
82227712638678862510272817700
433677733115839140356036818773
 
709681404405498840918712626000
List element: -5 negative integers not handled
Rank: 1 unrank not bijective
</pre>