Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
2
Task/Negative-base-numbers/00-META.yaml
Normal file
2
Task/Negative-base-numbers/00-META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Negative_base_numbers
|
||||
16
Task/Negative-base-numbers/00-TASK.txt
Normal file
16
Task/Negative-base-numbers/00-TASK.txt
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
Negative base numbers are an alternate way to encode numbers without the need for a minus sign. Various negative bases may be used including negadecimal (base -10), negabinary (-2) and negaternary (-3).<ref>[http://mathworld.wolfram.com/Negabinary.html Negabinary on Wolfram Mathworld]</ref><ref>[https://en.wikipedia.org/wiki/Negative_base Negative base] on Wikipedia</ref>
|
||||
|
||||
|
||||
;Task:
|
||||
|
||||
*Encode the decimal number 10 as negabinary (expect 11110)
|
||||
*Encode the decimal number 146 as negaternary (expect 21102)
|
||||
*Encode the decimal number 15 as negadecimal (expect 195)
|
||||
*In each of the above cases, convert the encoded number back to decimal.
|
||||
|
||||
|
||||
;extra credit:
|
||||
|
||||
* supply an integer, that when encoded to base -62 (or something "higher"), expresses the <br>name of the language being used (with correct capitalization). If the computer language has <br>non-alphanumeric characters, try to encode them into the negatory numerals, or use other <br>characters instead.
|
||||
<br><br>
|
||||
|
||||
42
Task/Negative-base-numbers/11l/negative-base-numbers.11l
Normal file
42
Task/Negative-base-numbers/11l/negative-base-numbers.11l
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
F encode_neg_base(=n, b)
|
||||
I n == 0
|
||||
R ‘0’
|
||||
[Int] out
|
||||
L n != 0
|
||||
(n, V rem) = divmod(n, b)
|
||||
I rem < 0
|
||||
n++
|
||||
rem -= b
|
||||
out.append(rem)
|
||||
R reversed(out).map(String).join(‘’)
|
||||
|
||||
F decode_neg_base(nstr, b)
|
||||
I nstr == ‘0’
|
||||
R 0
|
||||
V total = 0
|
||||
L(ch) reversed(nstr)
|
||||
V i = L.index
|
||||
total += Int(ch) * b ^ i
|
||||
R total
|
||||
|
||||
print(‘Encode 10 as negabinary (expect 11110)’)
|
||||
V result = encode_neg_base(10, -2)
|
||||
print(result)
|
||||
I decode_neg_base(result, -2) == 10
|
||||
print(‘Converted back to decimal’)
|
||||
E
|
||||
print(‘Error converting back to decimal’)
|
||||
print(‘Encode 146 as negaternary (expect 21102)’)
|
||||
result = encode_neg_base(146, -3)
|
||||
print(result)
|
||||
I decode_neg_base(result, -3) == 146
|
||||
print(‘Converted back to decimal’)
|
||||
E
|
||||
print(‘Error converting back to decimal’)
|
||||
print(‘Encode 15 as negadecimal (expect 195)’)
|
||||
result = encode_neg_base(15, -10)
|
||||
print(result)
|
||||
I decode_neg_base(result, -10) == 15
|
||||
print(‘Converted back to decimal’)
|
||||
E
|
||||
print(‘Error converting back to decimal’)
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
# Conversion to/from negative base numbers #
|
||||
# Note - no checks for valid bases or digits bases -2 .. -63 are handled #
|
||||
# A-Z represent the digits 11 .. 35, a-z represent the digits 36 .. 61 #
|
||||
# the digit 62 is represented by a space #
|
||||
|
||||
# 1 2 3 4 5 6 #
|
||||
# 01234567890123456789012345678901234567890123456789012 #
|
||||
[]CHAR base digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz "[ AT 0 ];
|
||||
|
||||
# returns s decoded to an integer from the negative base b #
|
||||
PRIO FROMNBASE = 9;
|
||||
OP FROMNBASE = ( STRING s, INT b )LONG INT:
|
||||
BEGIN
|
||||
LONG INT result := 0;
|
||||
LONG INT base multiplier := 1;
|
||||
FOR d pos FROM UPB s BY -1 TO LWB s DO
|
||||
INT digit = IF s[ d pos ] = " "
|
||||
THEN 62
|
||||
ELIF s[ d pos ] >= "a"
|
||||
THEN ( ABS s[ d pos ] + 36 ) - ABS "a"
|
||||
ELIF s[ d pos ] >= "A"
|
||||
THEN ( ABS s[ d pos ] + 10 ) - ABS "A"
|
||||
ELSE ABS s[ d pos ] - ABS "0"
|
||||
FI;
|
||||
result +:= base multiplier * digit;
|
||||
base multiplier *:= b
|
||||
OD;
|
||||
result
|
||||
END # FROMNBASE # ;
|
||||
OP FROMNBASE = ( CHAR c, INT b )LONG INT: STRING(c) FROMNBASE b;
|
||||
|
||||
# returns n encoded as a string in the negative base b #
|
||||
PRIO TONBASE = 9;
|
||||
OP TONBASE = ( LONG INT n, INT b )STRING:
|
||||
BEGIN
|
||||
STRING result := "";
|
||||
LONG INT v := n;
|
||||
WHILE
|
||||
INT d := SHORTEN IF v < 0 THEN - ( ABS v MOD b ) ELSE v MOD b FI;
|
||||
v OVERAB b;
|
||||
IF d < 0
|
||||
THEN
|
||||
d -:= b;
|
||||
v +:= 1
|
||||
FI;
|
||||
base digits[ d ] +=: result;
|
||||
v /= 0
|
||||
DO SKIP OD;
|
||||
result
|
||||
END # TONBASE # ;
|
||||
|
||||
# tests the TONBASE and FROMNBASE operators #
|
||||
PROC test n base = ( LONG INT number, INT base, STRING expected )VOID:
|
||||
BEGIN
|
||||
PROC expect = ( BOOL result )STRING: IF result THEN "" ELSE " INCORRECT" FI;
|
||||
STRING encoded = number TONBASE base;
|
||||
LONG INT decoded = encoded FROMNBASE base;
|
||||
print( ( whole( number, 0 ), " encodes to: ", encoded ) );
|
||||
print( ( " base ", whole( base, 0 ), expect( encoded = expected ), newline ) );
|
||||
print( ( encoded, " decodes to: ", whole( decoded, 0 ) ) );
|
||||
print( ( " base ", whole( base, 0 ), expect( decoded = number ), newline ) )
|
||||
END # test n base # ;
|
||||
|
||||
test n base( 10, -2, "11110" );
|
||||
test n base( 146, -3, "21102" );
|
||||
test n base( 15, -10, "195" );
|
||||
# The defining document for ALGOL 68 spells the name "Algol 68" on the cover, though inside it is "ALGOL 68" #
|
||||
# at the risk of "judging a language by it's cover", we use "Algol 68" as the name here... #
|
||||
test n base( - LONG 36492107981104, -63, "Algol 68" )
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
CHAR ARRAY digits="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz!"
|
||||
|
||||
INT FUNC MyMod(INT a,b)
|
||||
IF b>=0 THEN
|
||||
RETURN (a MOD b)
|
||||
FI
|
||||
RETURN (a-(b*(a/b)))
|
||||
|
||||
PROC Encode(INT n,base CHAR ARRAY res)
|
||||
INT i,d,len
|
||||
CHAR tmp
|
||||
|
||||
IF base<-63 OR base>-1 THEN Break() FI
|
||||
IF n=0 THEN SAssign(res,"0") FI
|
||||
|
||||
len=0
|
||||
WHILE n#0
|
||||
DO
|
||||
d=MyMod(n,base)
|
||||
n==/base
|
||||
IF d<0 THEN
|
||||
n==+1
|
||||
d==-base
|
||||
FI
|
||||
len==+1
|
||||
res(len)=digits(d+1)
|
||||
OD
|
||||
res(0)=len
|
||||
|
||||
FOR i=1 to len/2
|
||||
DO
|
||||
tmp=res(i)
|
||||
res(i)=res(len-i+1)
|
||||
res(len-i+1)=tmp
|
||||
OD
|
||||
RETURN
|
||||
|
||||
BYTE FUNC Index(CHAR ARRAY s CHAR c)
|
||||
BYTE i
|
||||
|
||||
FOR i=1 TO s(0)
|
||||
DO
|
||||
IF s(i)=c THEN RETURN (i) FI
|
||||
OD
|
||||
RETURN (0)
|
||||
|
||||
INT FUNC Decode(CHAR ARRAY s INT base)
|
||||
INT res,b,i,pos
|
||||
|
||||
IF base<-63 OR base>-1 THEN Break() FI
|
||||
IF s(0)=1 AND s(1)='0 THEN RETURN (0) FI
|
||||
|
||||
res=0
|
||||
b=1
|
||||
pos=s(0)
|
||||
WHILE pos>=1
|
||||
DO
|
||||
i=Index(digits,s(pos))-1
|
||||
res==+i*b
|
||||
b==*base
|
||||
pos==-1
|
||||
OD
|
||||
RETURN (res)
|
||||
|
||||
PROC Test(INT n,base)
|
||||
CHAR ARRAY s(20)
|
||||
INT v
|
||||
|
||||
Encode(n,base,s)
|
||||
PrintF("%I encoded in base %I is %S%E",n,base,s)
|
||||
v=Decode(s,base)
|
||||
PrintF("%S decoded in base %I is %I%E%E",s,base,v)
|
||||
RETURN
|
||||
|
||||
PROC Main()
|
||||
INT v
|
||||
Test(10,-2)
|
||||
Test(146,-3)
|
||||
Test(15,-10)
|
||||
Test(-568,-63)
|
||||
RETURN
|
||||
135
Task/Negative-base-numbers/Ada/negative-base-numbers.ada
Normal file
135
Task/Negative-base-numbers/Ada/negative-base-numbers.ada
Normal file
|
|
@ -0,0 +1,135 @@
|
|||
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
|
||||
|
||||
package Negative_Base_Numbers is
|
||||
|
||||
subtype base_t is Long_Long_Integer range -62 .. -1;
|
||||
|
||||
function Encode_Negative_Base
|
||||
(N : in Long_Long_Integer; Base : in base_t) return Unbounded_String;
|
||||
function Decode_Negative_Base
|
||||
(N : in Unbounded_String; Base : in base_t) return Long_Long_Integer;
|
||||
|
||||
end Negative_Base_Numbers;
|
||||
|
||||
with Ada.Text_IO;
|
||||
package body Negative_Base_Numbers is
|
||||
|
||||
Digit_Chars : constant String :=
|
||||
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
--------------------------
|
||||
-- Encode_Negative_Base --
|
||||
--------------------------
|
||||
|
||||
function Encode_Negative_Base
|
||||
(N : in Long_Long_Integer; Base : in base_t) return Unbounded_String
|
||||
is
|
||||
procedure swap (a, b : in out Character) is
|
||||
temp : Character := a;
|
||||
begin
|
||||
a := b;
|
||||
b := temp;
|
||||
end swap;
|
||||
|
||||
Result : Unbounded_String := Null_Unbounded_String;
|
||||
Local_N : Long_Long_Integer := N;
|
||||
Remainder : Long_Long_Integer;
|
||||
|
||||
begin
|
||||
if Local_N = 0 then
|
||||
Result := To_Unbounded_String ("0");
|
||||
else
|
||||
while Local_N /= 0 loop
|
||||
Remainder := Local_N rem Base;
|
||||
Local_N := Local_N / Base;
|
||||
if Remainder < 0 then
|
||||
Local_N := Local_N + 1;
|
||||
Remainder := Remainder - Base;
|
||||
end if;
|
||||
Append (Result, Digit_Chars (Integer (Remainder + 1)));
|
||||
end loop;
|
||||
end if;
|
||||
|
||||
declare
|
||||
Temp_Result : String := To_String (Result);
|
||||
Low : Positive := Temp_Result'First;
|
||||
High : Positive := Temp_Result'Last;
|
||||
begin
|
||||
while Low < High loop
|
||||
swap (Temp_Result (Low), Temp_Result (High));
|
||||
Low := Low + 1;
|
||||
High := High - 1;
|
||||
end loop;
|
||||
Result := To_Unbounded_String (Temp_Result);
|
||||
end;
|
||||
|
||||
return Result;
|
||||
end Encode_Negative_Base;
|
||||
|
||||
--------------------------
|
||||
-- Decode_Negative_Base --
|
||||
--------------------------
|
||||
|
||||
function Decode_Negative_Base
|
||||
(N : in Unbounded_String; Base : in base_t) return Long_Long_Integer
|
||||
is
|
||||
Total : Long_Long_Integer := 0;
|
||||
bb : Long_Long_Integer := 1;
|
||||
Temp : String := To_String (N);
|
||||
begin
|
||||
if Length (N) = 0 or else (Length (N) = 1 and Element (N, 1) = '0') then
|
||||
return 0;
|
||||
end if;
|
||||
|
||||
for char of reverse Temp loop
|
||||
for J in Digit_Chars'Range loop
|
||||
if char = Digit_Chars (J) then
|
||||
Total := Total + Long_Long_Integer (J - 1) * bb;
|
||||
bb := bb * Base;
|
||||
end if;
|
||||
end loop;
|
||||
end loop;
|
||||
|
||||
return Total;
|
||||
end Decode_Negative_Base;
|
||||
|
||||
end Negative_Base_Numbers;
|
||||
|
||||
with Ada.Text_IO; use Ada.Text_IO;
|
||||
with Negative_Base_Numbers; use Negative_Base_Numbers;
|
||||
with Ada.Strings.Fixed; use Ada.Strings.Fixed;
|
||||
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
|
||||
|
||||
procedure Main is
|
||||
|
||||
procedure driver (N : in Long_Long_Integer; B : in base_t) is
|
||||
package long_IO is new Integer_IO (Long_Long_Integer);
|
||||
use long_IO;
|
||||
|
||||
ns : Unbounded_String := Encode_Negative_Base (N, B);
|
||||
P : Long_Long_Integer;
|
||||
Output : String (1 .. 12);
|
||||
|
||||
begin
|
||||
Put (Item => N, Width => 12);
|
||||
Put (" encoded in base ");
|
||||
Put (Item => B, Width => 3);
|
||||
Put_Line (" = " & To_String (ns));
|
||||
|
||||
Move
|
||||
(Source => To_String (ns), Target => Output,
|
||||
Justify => Ada.Strings.Right);
|
||||
P := Decode_Negative_Base (ns, B);
|
||||
Put (Output & " decoded in base ");
|
||||
Put (Item => B, Width => 3);
|
||||
Put (" = ");
|
||||
Put (Item => P, Width => 1);
|
||||
New_Line (2);
|
||||
end driver;
|
||||
|
||||
begin
|
||||
driver (10, -2);
|
||||
driver (146, -3);
|
||||
driver (15, -10);
|
||||
driver (36_058, -62);
|
||||
end Main;
|
||||
75
Task/Negative-base-numbers/C++/negative-base-numbers.cpp
Normal file
75
Task/Negative-base-numbers/C++/negative-base-numbers.cpp
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
const std::string DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
std::string encodeNegativeBase(int64_t n, int b) {
|
||||
if (b < -62 || b > -1) {
|
||||
throw std::runtime_error("Argument out of range: b");
|
||||
}
|
||||
if (n == 0) {
|
||||
return "0";
|
||||
}
|
||||
|
||||
std::string output;
|
||||
int64_t nn = n;
|
||||
while (nn != 0) {
|
||||
int rem = nn % b;
|
||||
nn /= b;
|
||||
if (rem < 0) {
|
||||
nn++;
|
||||
rem -= b;
|
||||
}
|
||||
output += DIGITS[rem];
|
||||
}
|
||||
|
||||
std::reverse(output.begin(), output.end());
|
||||
return output;
|
||||
}
|
||||
|
||||
int64_t decodeNegativeBase(const std::string& ns, int b) {
|
||||
if (b < -62 || b > -1) {
|
||||
throw std::runtime_error("Argument out of range: b");
|
||||
}
|
||||
if (ns == "0") {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int64_t total = 0;
|
||||
int64_t bb = 1;
|
||||
|
||||
for (auto it = ns.crbegin(); it != ns.crend(); it = std::next(it)) {
|
||||
auto ptr = std::find(DIGITS.cbegin(), DIGITS.cend(), *it);
|
||||
if (ptr != DIGITS.cend()) {
|
||||
auto idx = ptr - DIGITS.cbegin();
|
||||
total += idx * bb;
|
||||
}
|
||||
bb *= b;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
int main() {
|
||||
using namespace std;
|
||||
|
||||
vector<pair<int64_t, int>> nbl({
|
||||
make_pair(10, -2),
|
||||
make_pair(146, -3),
|
||||
make_pair(15, -10),
|
||||
make_pair(142961, -62)
|
||||
});
|
||||
|
||||
for (auto& p : nbl) {
|
||||
string ns = encodeNegativeBase(p.first, p.second);
|
||||
cout << setw(12) << p.first << " encoded in base " << setw(3) << p.second << " = " << ns.c_str() << endl;
|
||||
|
||||
int64_t n = decodeNegativeBase(ns, p.second);
|
||||
cout << setw(12) << ns.c_str() << " decoded in base " << setw(3) << p.second << " = " << n << endl;
|
||||
|
||||
cout << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
64
Task/Negative-base-numbers/C-sharp/negative-base-numbers.cs
Normal file
64
Task/Negative-base-numbers/C-sharp/negative-base-numbers.cs
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace NegativeBaseNumbers {
|
||||
class Program {
|
||||
const string DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
static string EncodeNegativeBase(long n, int b) {
|
||||
if (b < -62 || b > -1) {
|
||||
throw new ArgumentOutOfRangeException("b");
|
||||
}
|
||||
if (n == 0) {
|
||||
return "0";
|
||||
}
|
||||
StringBuilder output = new StringBuilder();
|
||||
long nn = n;
|
||||
while (nn != 0) {
|
||||
int rem = (int)(nn % b);
|
||||
nn /= b;
|
||||
if (rem < 0) {
|
||||
nn++;
|
||||
rem -= b;
|
||||
}
|
||||
output.Append(DIGITS[rem]);
|
||||
}
|
||||
return new string(output.ToString().Reverse().ToArray());
|
||||
}
|
||||
|
||||
static long DecodeNegativeBase(string ns, int b) {
|
||||
if (b < -62 || b > -1) {
|
||||
throw new ArgumentOutOfRangeException("b");
|
||||
}
|
||||
if (ns == "0") {
|
||||
return 0;
|
||||
}
|
||||
long total = 0;
|
||||
long bb = 1;
|
||||
for (int i = ns.Length - 1; i >= 0; i--) {
|
||||
char c = ns[i];
|
||||
total += DIGITS.IndexOf(c) * bb;
|
||||
bb *= b;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
static void Main(string[] args) {
|
||||
List<Tuple<long, int>> nbl = new List<Tuple<long, int>>() {
|
||||
new Tuple<long, int>(10,-2),
|
||||
new Tuple<long, int>(146,-3),
|
||||
new Tuple<long, int>(15,-10),
|
||||
new Tuple<long, int>(-34025238427,-62),
|
||||
};
|
||||
foreach (var p in nbl) {
|
||||
string ns = EncodeNegativeBase(p.Item1, p.Item2);
|
||||
Console.WriteLine("{0,12} encoded in base {1,-3} = {2}", p.Item1, p.Item2, ns);
|
||||
long n = DecodeNegativeBase(ns, p.Item2);
|
||||
Console.WriteLine("{0,12} decoded in base {1,-3} = {2}", ns, p.Item2, n);
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
103
Task/Negative-base-numbers/C/negative-base-numbers.c
Normal file
103
Task/Negative-base-numbers/C/negative-base-numbers.c
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
#include <stdio.h>
|
||||
|
||||
const char DIGITS[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
const int DIGITS_LEN = 64;
|
||||
|
||||
void encodeNegativeBase(long n, long base, char *out) {
|
||||
char *ptr = out;
|
||||
|
||||
if (base > -1 || base < -62) {
|
||||
/* Bounds check*/
|
||||
out = "";
|
||||
return;
|
||||
}
|
||||
if (n == 0) {
|
||||
/* Trivial case */
|
||||
out = "0";
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert the number into a string (in reverse) */
|
||||
while (n != 0) {
|
||||
long rem = n % base;
|
||||
n = n / base;
|
||||
if (rem < 0) {
|
||||
n++;
|
||||
rem = rem - base;
|
||||
}
|
||||
*ptr = DIGITS[rem];
|
||||
ptr++;
|
||||
}
|
||||
*ptr = 0;
|
||||
|
||||
/* Reverse the current string to get the final result */
|
||||
ptr--;
|
||||
while (out < ptr) {
|
||||
char t = *out;
|
||||
*out = *ptr;
|
||||
*ptr = t;
|
||||
out++;
|
||||
ptr--;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
long decodeNegativeBase(const char* ns, long base) {
|
||||
long value, bb;
|
||||
int i;
|
||||
const char *ptr;
|
||||
|
||||
if (base < -62 || base > -1) {
|
||||
/* Bounds check */
|
||||
return 0;
|
||||
}
|
||||
if (ns[0] == 0 || (ns[0] == '0' && ns[1] == 0)) {
|
||||
/* Trivial case */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find the end of the string */
|
||||
ptr = ns;
|
||||
while (*ptr != 0) {
|
||||
ptr++;
|
||||
}
|
||||
|
||||
/* Convert */
|
||||
value = 0;
|
||||
bb = 1;
|
||||
ptr--;
|
||||
while (ptr >= ns) {
|
||||
for (i = 0; i < DIGITS_LEN; i++) {
|
||||
if (*ptr == DIGITS[i]) {
|
||||
value = value + i * bb;
|
||||
bb = bb * base;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ptr--;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void driver(long n, long b) {
|
||||
char buf[64];
|
||||
long value;
|
||||
|
||||
encodeNegativeBase(n, b, buf);
|
||||
printf("%12d encoded in base %3d = %12s\n", n, b, buf);
|
||||
|
||||
value = decodeNegativeBase(buf, b);
|
||||
printf("%12s decoded in base %3d = %12d\n", buf, b, value);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main() {
|
||||
driver(10, -2);
|
||||
driver(146, -3);
|
||||
driver(15, -10);
|
||||
driver(12, -62);
|
||||
|
||||
return 0;
|
||||
}
|
||||
62
Task/Negative-base-numbers/D/negative-base-numbers.d
Normal file
62
Task/Negative-base-numbers/D/negative-base-numbers.d
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
import std.stdio;
|
||||
|
||||
immutable DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
void main() {
|
||||
driver(10, -2);
|
||||
driver(146, -3);
|
||||
driver(15, -10);
|
||||
driver(13, -62);
|
||||
}
|
||||
|
||||
void driver(long n, int b) {
|
||||
string ns = encodeNegBase(n, b);
|
||||
writefln("%12d encoded in base %3d = %12s", n, b, ns);
|
||||
|
||||
long p = decodeNegBase(ns, b);
|
||||
writefln("%12s decoded in base %3d = %12d", ns, b, p);
|
||||
|
||||
writeln;
|
||||
}
|
||||
|
||||
string encodeNegBase(long n, int b) in {
|
||||
import std.exception : enforce;
|
||||
enforce(b <= -1 && b >= -62);
|
||||
} body {
|
||||
if (n==0) return "0";
|
||||
char[] output;
|
||||
long nn = n;
|
||||
while (nn != 0) {
|
||||
int rem = nn % b;
|
||||
nn /= b;
|
||||
if (rem < 0) {
|
||||
nn++;
|
||||
rem -= b;
|
||||
}
|
||||
output ~= DIGITS[rem];
|
||||
}
|
||||
|
||||
import std.algorithm : reverse;
|
||||
|
||||
reverse(output);
|
||||
return cast(string) output;
|
||||
}
|
||||
|
||||
long decodeNegBase(string ns, int b) in {
|
||||
import std.exception : enforce;
|
||||
enforce(b <= -1 && b >= -62);
|
||||
} body {
|
||||
if (ns == "0") return 0;
|
||||
long total = 0;
|
||||
long bb = 1;
|
||||
foreach_reverse (c; ns) {
|
||||
foreach(i,d; DIGITS) {
|
||||
if (c==d) {
|
||||
total += i * bb;
|
||||
bb *= b;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
//I provide 2 fuctions D2N takes a radix and an integer returning a sequence of integers
|
||||
// N2D takse a radix and a sequence of integers returning an integer
|
||||
//Note that the radix may be either positive or negative. Nigel Galloway, May 10th., 2019
|
||||
let D2N n g=if g=0 then seq[0] else Seq.unfold(fun g->let α,β=g/n,g%n in match (compare g 0,β) with
|
||||
(0,_)->None
|
||||
|(1,_) |(_,0)->Some(β,α)
|
||||
|_->Some(g-(α+1)*n,α+1)) g|>Seq.rev
|
||||
let N2D n g=fst(Seq.foldBack(fun g (Σ,α)->(Σ+α*g,n*α)) g (0,1))
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
let t0,t146,t10,t15=D2N -13 0,D2N -3 146,D2N -2 10,D2N -10 15
|
||||
Seq.iter(fun n->Seq.iter(printf "%d ")n; printfn "")[t0;t146;t10;t15]
|
||||
Seq.iter(printfn "%d ")[N2D -13 t0;N2D -3 t146;N2D -2 t10;N2D -10 t15]
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
USING: formatting fry kernel make math math.combinators
|
||||
math.extras math.functions math.parser sequences ;
|
||||
|
||||
: /mod* ( x y -- z w )
|
||||
[ /mod ] keep '[ [ 1 + ] dip _ abs + ] when-negative ;
|
||||
|
||||
: >nega ( n radix -- str )
|
||||
[ '[ _ /mod* # ] until-zero ] "" make reverse ;
|
||||
|
||||
: nega> ( str radix -- n )
|
||||
swap <reversed> [ ^ swap digit> * ] with map-index sum ;
|
||||
|
||||
: .round-trip ( n radix -- )
|
||||
dupd [ >nega ] keep 2dup 2dup nega>
|
||||
"%d_10 is %s_%d\n%s_%d is %d_10\n\n" printf ;
|
||||
|
||||
10 -2 146 -3 15 -10 [ .round-trip ] 2tri@
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
#define DIGITS "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
Dim cadena(63) As String
|
||||
|
||||
Function mod2(a As Long, b As Integer) As Long
|
||||
Return a - (a \ b) * b
|
||||
End Function
|
||||
|
||||
Function StrReverse(Byval text As String) As String
|
||||
Dim As String text2 = text
|
||||
Dim As Integer x, lt = Len(text)
|
||||
|
||||
For x = 0 To lt Shr 1 - 1
|
||||
Swap text2[x], text2[lt - x - 1]
|
||||
Next x
|
||||
Return text2
|
||||
End Function
|
||||
|
||||
Function EncodeNegativeBase(Byval n As Long, base_ As Integer) As String
|
||||
Dim As Long Puntero, idx, rem_
|
||||
Dim result As String
|
||||
|
||||
If base_ > -1 Or base_ < -62 Then
|
||||
Return result
|
||||
Else
|
||||
If n = 0 Then
|
||||
Return "0"
|
||||
Else
|
||||
Puntero = 0
|
||||
Do While n <> 0
|
||||
rem_ = mod2(n, base_)
|
||||
n \= base_
|
||||
If rem_ < 0 Then
|
||||
n += 1
|
||||
rem_ = rem_ - base_
|
||||
End If
|
||||
result &= Mid(DIGITS, rem_ + 1, 1)
|
||||
Loop
|
||||
End If
|
||||
End If
|
||||
Return StrReverse(result)
|
||||
End Function
|
||||
|
||||
Function DecodeNegativeBase(ns As String, base_ As Integer) As Long
|
||||
Dim As Long total, bb
|
||||
Dim As Integer i, j
|
||||
|
||||
If base_ < -62 Or base_ > -1 Then Return 0
|
||||
If Mid(ns, 1, 1) = "0" Or (Mid(ns, 1, 1) = "0" And Mid(ns, 2, 1) = "0") Then Return 0
|
||||
i = Len(ns)
|
||||
total = 0
|
||||
bb = 1
|
||||
Do While i >= 1
|
||||
j = Instr(DIGITS, Mid(ns, i, 1)) - 1
|
||||
total += j * bb
|
||||
bb *= base_
|
||||
i -= 1
|
||||
Loop
|
||||
Return total
|
||||
End Function
|
||||
|
||||
Sub Driver(n As Long, b As Integer)
|
||||
Dim As String ns = EncodeNegativeBase(n, b)
|
||||
Print Str(n); " encoded in base "; b; " = "; ns
|
||||
Dim As Long p = DecodeNegativeBase(ns, b)
|
||||
Print ns; " decoded in base "; b; " ="; p
|
||||
Print
|
||||
End Sub
|
||||
|
||||
Driver 10, -2
|
||||
Driver 146, -3
|
||||
Driver 15, -10
|
||||
Driver 118492, -62
|
||||
|
||||
Sleep
|
||||
74
Task/Negative-base-numbers/Go/negative-base-numbers.go
Normal file
74
Task/Negative-base-numbers/Go/negative-base-numbers.go
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
func reverse(bs []byte) []byte {
|
||||
for i, j := 0, len(bs)-1; i < len(bs)/2; i, j = i+1, j-1 {
|
||||
bs[i], bs[j] = bs[j], bs[i]
|
||||
}
|
||||
return bs
|
||||
}
|
||||
|
||||
func encodeNegBase(n, b int64) (string, error) {
|
||||
if b < -62 || b > -1 {
|
||||
return "", fmt.Errorf("base must be between -62 and -1 inclusive")
|
||||
}
|
||||
if n == 0 {
|
||||
return "0", nil
|
||||
}
|
||||
var out []byte
|
||||
for n != 0 {
|
||||
rem := n % b
|
||||
n /= b
|
||||
if rem < 0 {
|
||||
n++
|
||||
rem -= b
|
||||
}
|
||||
out = append(out, digits[int(rem)])
|
||||
}
|
||||
reverse(out)
|
||||
return string(out), nil
|
||||
}
|
||||
|
||||
func decodeNegBase(ns string, b int64) (int64, error) {
|
||||
if b < -62 || b > -1 {
|
||||
return 0, fmt.Errorf("base must be between -62 and -1 inclusive")
|
||||
}
|
||||
if ns == "0" {
|
||||
return 0, nil
|
||||
}
|
||||
total := int64(0)
|
||||
bb := int64(1)
|
||||
bs := []byte(ns)
|
||||
reverse(bs)
|
||||
for _, c := range bs {
|
||||
total += int64(strings.IndexByte(digits, c)) * bb
|
||||
bb *= b
|
||||
}
|
||||
return total, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
numbers := []int64{10, 146, 15, -942, 1488588316238}
|
||||
bases := []int64{-2, -3, -10, -62, -62}
|
||||
for i := 0; i < len(numbers); i++ {
|
||||
n := numbers[i]
|
||||
b := bases[i]
|
||||
ns, err := encodeNegBase(n, b)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("%13d encoded in base %-3d = %s\n", n, b, ns)
|
||||
n, err = decodeNegBase(ns, b)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Printf("%13s decoded in base %-3d = %d\n\n", ns, b, n)
|
||||
}
|
||||
}
|
||||
33
Task/Negative-base-numbers/Haskell/negative-base-numbers.hs
Normal file
33
Task/Negative-base-numbers/Haskell/negative-base-numbers.hs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
import Data.Char (chr, ord)
|
||||
import Numeric (showIntAtBase)
|
||||
|
||||
-- The remainder and quotient of n/d, where the remainder is guaranteed to be
|
||||
-- non-negative. The divisor, d, is assumed to be negative.
|
||||
quotRemP :: Integral a => a -> a -> (a, a)
|
||||
quotRemP n d = let (q, r) = quotRem n d
|
||||
in if r < 0 then (q+1, r-d) else (q, r)
|
||||
|
||||
-- Convert the number n to base b, where b is assumed to be less than zero.
|
||||
toNegBase :: Integral a => a -> a -> a
|
||||
toNegBase b n = let (q, r) = quotRemP n b
|
||||
in if q == 0 then r else negate b * toNegBase b q + r
|
||||
|
||||
-- Convert n to a string, where n is assumed to be a base b number, with b less
|
||||
-- than zero.
|
||||
showAtBase :: (Integral a, Show a) => a -> a -> String
|
||||
showAtBase b n = showIntAtBase (abs b) charOf n ""
|
||||
where charOf m | m < 10 = chr $ m + ord '0'
|
||||
| m < 36 = chr $ m + ord 'a' - 10
|
||||
| otherwise = '?'
|
||||
|
||||
-- Print a number in base b, where b is assumed to be less than zero.
|
||||
printAtBase :: (Integral a, Show a) => a -> a -> IO ()
|
||||
printAtBase b = putStrLn . showAtBase b . toNegBase b
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
printAtBase (-2) 10
|
||||
printAtBase (-3) 146
|
||||
printAtBase (-10) 15
|
||||
printAtBase (-16) 107
|
||||
printAtBase (-36) 41371458
|
||||
53
Task/Negative-base-numbers/Java/negative-base-numbers.java
Normal file
53
Task/Negative-base-numbers/Java/negative-base-numbers.java
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class NegativeBaseNumbers {
|
||||
private static final String DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
private static String encodeNegBase(long n, int b) {
|
||||
if (b < -62 || b > -1) throw new IllegalArgumentException("Parameter b is out of bounds");
|
||||
if (n == 0) return "0";
|
||||
StringBuilder out = new StringBuilder();
|
||||
long nn = n;
|
||||
while (nn != 0) {
|
||||
int rem = (int) (nn % b);
|
||||
nn /= b;
|
||||
if (rem < 0) {
|
||||
nn++;
|
||||
rem -= b;
|
||||
}
|
||||
out.append(DIGITS.charAt(rem));
|
||||
}
|
||||
out.reverse();
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
private static long decodeNegBase(String ns, int b) {
|
||||
if (b < -62 || b > -1) throw new IllegalArgumentException("Parameter b is out of bounds");
|
||||
if (Objects.equals(ns, "0")) return 0;
|
||||
long total = 0;
|
||||
long bb = 1;
|
||||
for (int i = ns.length() - 1; i >= 0; i--) {
|
||||
char c = ns.charAt(i);
|
||||
total += DIGITS.indexOf(c) * bb;
|
||||
bb *= b;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
List<Map.Entry<Long, Integer>> nbl = List.of(
|
||||
Map.entry(10L, -2),
|
||||
Map.entry(146L, -3),
|
||||
Map.entry(15L, -10),
|
||||
Map.entry(-4393346L, -62)
|
||||
);
|
||||
for (Map.Entry<Long, Integer> p : nbl) {
|
||||
String ns = encodeNegBase(p.getKey(), p.getValue());
|
||||
System.out.printf("%12d encoded in base %-3d = %s\n", p.getKey(), p.getValue(), ns);
|
||||
long n = decodeNegBase(ns, p.getValue());
|
||||
System.out.printf("%12s decoded in base %-3d = %d\n\n", ns, p.getValue(), n);
|
||||
}
|
||||
}
|
||||
}
|
||||
1
Task/Negative-base-numbers/Jq/negative-base-numbers-1.jq
Normal file
1
Task/Negative-base-numbers/Jq/negative-base-numbers-1.jq
Normal file
|
|
@ -0,0 +1 @@
|
|||
def trunc: if . >= 0 then floor else -(-(.)|trunc) end;
|
||||
34
Task/Negative-base-numbers/Jq/negative-base-numbers-2.jq
Normal file
34
Task/Negative-base-numbers/Jq/negative-base-numbers-2.jq
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
def negbase($b):
|
||||
if ($b >= 0) then error("negbase requires negative base")
|
||||
elif . == 0 then "0"
|
||||
else {n: ., ans: ""}
|
||||
| until(.n == 0;
|
||||
.r = ((.n % $b))
|
||||
| .n = ((.n / $b) | trunc)
|
||||
| if .r < 0 then .n += 1 | .r -= $b else . end
|
||||
| .ans = (.r|tostring) + .ans )
|
||||
| .ans
|
||||
end ;
|
||||
|
||||
def sigma(stream): reduce stream as $x (null; .+$x);
|
||||
|
||||
def invnegbase($b):
|
||||
(explode | reverse | map(. - 48)) as $s
|
||||
| sigma( range(0; $s|length) | ($s[.] * pow($b; .)));
|
||||
|
||||
def testset: {
|
||||
"11110": [10, -2],
|
||||
"21102": [146, -3],
|
||||
"195": [15, -10]
|
||||
};
|
||||
|
||||
def test: testset
|
||||
| to_entries[]
|
||||
| .value[0] as $n
|
||||
| .value[1] as $base
|
||||
| ($n|negbase($base)) as $neg
|
||||
| ($neg | invnegbase($base)) as $invneg
|
||||
| [.key == $neg, $n == $invneg]
|
||||
;
|
||||
|
||||
test
|
||||
3
Task/Negative-base-numbers/Jq/negative-base-numbers-3.jq
Normal file
3
Task/Negative-base-numbers/Jq/negative-base-numbers-3.jq
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
[true,true]
|
||||
[true,true]
|
||||
[true,true]
|
||||
26
Task/Negative-base-numbers/Julia/negative-base-numbers.julia
Normal file
26
Task/Negative-base-numbers/Julia/negative-base-numbers.julia
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
function negbase(n, b)
|
||||
if n == 0 return "0" end
|
||||
out = IOBuffer()
|
||||
while n != 0
|
||||
n, r = divrem(n, b)
|
||||
if r < 0
|
||||
n += 1
|
||||
r -= b
|
||||
end
|
||||
print(out, r)
|
||||
end
|
||||
return reverse(String(out))
|
||||
end
|
||||
|
||||
invnegbase(nst, b) = sum((ch - '0') * b ^ (i - 1) for (i, ch) in enumerate(reverse(nst)))
|
||||
|
||||
testset = Dict(
|
||||
(10, -2) => "11110",
|
||||
(143, -3) => "21102",
|
||||
(15, -10) => "195")
|
||||
|
||||
for ((num, base), rst) in testset
|
||||
encoded = negbase(num, base)
|
||||
decoded = invnegbase(encoded, base)
|
||||
println("\nencode $num in base $base:\n-> expected: $rst\n-> resulted: $encoded\n-> decoded: $decoded")
|
||||
end
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
// version 1.1.2
|
||||
|
||||
const val DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
fun encodeNegBase(n: Long, b: Int): String {
|
||||
require(b in -62 .. -1)
|
||||
if (n == 0L) return "0"
|
||||
val out = mutableListOf<Char>()
|
||||
var nn = n
|
||||
while (nn != 0L) {
|
||||
var rem = (nn % b).toInt()
|
||||
nn /= b
|
||||
if (rem < 0) {
|
||||
nn++
|
||||
rem -= b
|
||||
}
|
||||
out.add(DIGITS[rem])
|
||||
}
|
||||
out.reverse()
|
||||
return out.joinToString("")
|
||||
}
|
||||
|
||||
fun decodeNegBase(ns: String, b: Int): Long {
|
||||
require(b in -62 .. -1)
|
||||
if (ns == "0") return 0
|
||||
var total = 0L
|
||||
var bb = 1L
|
||||
for (c in ns.reversed()) {
|
||||
total += DIGITS.indexOf(c) * bb
|
||||
bb *= b
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
fun main(args:Array<String>) {
|
||||
val nbl = listOf(10L to -2, 146L to -3, 15L to -10, -17596769891 to -62)
|
||||
for (p in nbl) {
|
||||
val ns = encodeNegBase(p.first, p.second)
|
||||
System.out.printf("%12d encoded in base %-3d = %s\n", p.first, p.second, ns)
|
||||
val n = decodeNegBase(ns, p.second)
|
||||
System.out.printf("%12s decoded in base %-3d = %d\n\n", ns, p.second, n)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
EncodeBase[number_,base_]:=Module[{
|
||||
out={},
|
||||
rem,n=number,b=base
|
||||
},
|
||||
While[
|
||||
n!=0,
|
||||
{n,rem}={Floor[Divide[n,b]],Mod[n,b]};
|
||||
If[
|
||||
rem<0,
|
||||
n+=1;
|
||||
rem-=b
|
||||
];
|
||||
PrependTo[out,rem]
|
||||
];
|
||||
out
|
||||
];
|
||||
DecodeBase[list_,base_]:=Total[list*base^Range[Length[list]-1,0,-1]];
|
||||
|
||||
Print[EncodeNegBase[10,-2],"=",DecodeBase[EncodeNegBase[10,-2],-2]];
|
||||
Print[EncodeNegBase[146,-3],"=",DecodeBase[EncodeNegBase[146,-3],-3]];
|
||||
Print[EncodeNegBase[15,-10],"=",DecodeBase[EncodeNegBase[15,-10],-10]];
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
DecodeBase[ToCharacterCode[$Version], -126](*ascii 1-byte encoding*)
|
||||
DecodeBase[ToCharacterCode[$Version], -(2^16 - 1)](*2-byte encoding*)
|
||||
111
Task/Negative-base-numbers/Modula-2/negative-base-numbers.mod2
Normal file
111
Task/Negative-base-numbers/Modula-2/negative-base-numbers.mod2
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
MODULE NegativeBase;
|
||||
FROM FormatString IMPORT FormatString;
|
||||
FROM Terminal IMPORT WriteString,WriteLn,ReadChar;
|
||||
|
||||
CONST DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
TYPE String = ARRAY[0..63] OF CHAR;
|
||||
|
||||
PROCEDURE EncodeNegativeBase(n : LONGINT; base : LONGINT) : String;
|
||||
PROCEDURE Mod(a,b : LONGINT) : LONGINT;
|
||||
BEGIN
|
||||
RETURN a - (a / b) * b
|
||||
END Mod;
|
||||
|
||||
PROCEDURE Swap(VAR a,b : CHAR);
|
||||
VAR t : CHAR;
|
||||
BEGIN
|
||||
t := a;
|
||||
a := b;
|
||||
b := t
|
||||
END Swap;
|
||||
VAR
|
||||
ptr,idx : CARDINAL;
|
||||
rem : LONGINT;
|
||||
result : String;
|
||||
BEGIN
|
||||
IF (base > -1) OR (base < -62) THEN
|
||||
RETURN result
|
||||
ELSIF n = 0 THEN
|
||||
result := "0"
|
||||
ELSE
|
||||
ptr := 0;
|
||||
WHILE n # 0 DO
|
||||
rem := Mod(n, base);
|
||||
n := n / base;
|
||||
IF rem < 0 THEN
|
||||
INC(n);
|
||||
rem := rem - base
|
||||
END;
|
||||
result[ptr] := DIGITS[rem];
|
||||
INC(ptr);
|
||||
END
|
||||
END;
|
||||
result[ptr] := 0C;
|
||||
|
||||
idx := 0;
|
||||
DEC(ptr);
|
||||
WHILE idx < ptr DO
|
||||
Swap(result[idx], result[ptr]);
|
||||
INC(idx);
|
||||
DEC(ptr)
|
||||
END;
|
||||
|
||||
RETURN result
|
||||
END EncodeNegativeBase;
|
||||
|
||||
PROCEDURE DecodeNegativeBase(ns : String; base : LONGINT) : LONGINT;
|
||||
VAR
|
||||
total,bb,i,j : LONGINT;
|
||||
BEGIN
|
||||
IF (base < -62) OR (base > -1) THEN
|
||||
RETURN 0
|
||||
ELSIF (ns[0] = 0C) OR ((ns[0] = '0') AND (ns[1] = 0C)) THEN
|
||||
RETURN 0
|
||||
ELSE
|
||||
FOR i:=0 TO HIGH(ns) DO
|
||||
IF ns[i] = 0C THEN
|
||||
BREAK
|
||||
END
|
||||
END;
|
||||
DEC(i);
|
||||
|
||||
total := 0;
|
||||
bb := 1;
|
||||
WHILE i >= 0 DO
|
||||
FOR j:=0 TO HIGH(DIGITS) DO
|
||||
IF ns[i] = DIGITS[j] THEN
|
||||
total := total + j * bb;
|
||||
bb := bb * base;
|
||||
BREAK
|
||||
END
|
||||
END;
|
||||
DEC(i)
|
||||
END;
|
||||
END;
|
||||
RETURN total
|
||||
END DecodeNegativeBase;
|
||||
|
||||
PROCEDURE Driver(n,b : LONGINT);
|
||||
VAR
|
||||
ns,buf : String;
|
||||
p : LONGINT;
|
||||
BEGIN
|
||||
ns := EncodeNegativeBase(n, b);
|
||||
FormatString("%12l encoded in base %3l = %12s\n", buf, n, b, ns);
|
||||
WriteString(buf);
|
||||
|
||||
p := DecodeNegativeBase(ns, b);
|
||||
FormatString("%12s decoded in base %3l = %12l\n", buf, ns, b, p);
|
||||
WriteString(buf);
|
||||
|
||||
WriteLn
|
||||
END Driver;
|
||||
|
||||
BEGIN
|
||||
Driver(10, -2);
|
||||
Driver(146, -3);
|
||||
Driver(15, -10);
|
||||
Driver(-19425187910, -62);
|
||||
|
||||
ReadChar
|
||||
END NegativeBase.
|
||||
51
Task/Negative-base-numbers/Nim/negative-base-numbers.nim
Normal file
51
Task/Negative-base-numbers/Nim/negative-base-numbers.nim
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import algorithm, sugar, tables
|
||||
|
||||
const
|
||||
Digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
Values = collect(initTable):
|
||||
for i, c in Digits: {c: i} # Maps the digits to their values in base 10.
|
||||
|
||||
type Number = object
|
||||
## Representation of a number in any base.
|
||||
base: int
|
||||
value: string
|
||||
|
||||
func toBase(n, base: int): Number =
|
||||
## Convert an integer into a number in base 'base'.
|
||||
assert base notin -1..1, "wrong value for base: " & $base
|
||||
if n == 0: return Number(base: base, value: "0")
|
||||
result.base = base
|
||||
var n = n
|
||||
while n != 0:
|
||||
var m = n mod base
|
||||
n = n div base
|
||||
if m < 0:
|
||||
inc m, abs(base)
|
||||
inc n
|
||||
result.value.add Digits[m]
|
||||
result.value.reverse()
|
||||
|
||||
func `$`(n: Number): string =
|
||||
## String representation of a number.
|
||||
$n.value
|
||||
|
||||
func toInt(n: Number): int =
|
||||
## Convert a number in some base into an integer in base 10.
|
||||
for d in n.value:
|
||||
result = n.base * result + Values[d]
|
||||
|
||||
|
||||
when isMainModule:
|
||||
|
||||
proc process(n, base: int) =
|
||||
let s = n.toBase(base)
|
||||
echo "The value ", n, " is encoded in base ", base, " as: ", s
|
||||
echo "and is decoded back in base 10 as: ", s.toInt
|
||||
echo ""
|
||||
|
||||
process(10, -2)
|
||||
process(146, -3)
|
||||
process(15, -10)
|
||||
|
||||
const Nim = Number(base: -62, value: "Nim")
|
||||
echo "The string “Nim” is decoded from base -62 to base 10 as: ", Nim.toInt
|
||||
59
Task/Negative-base-numbers/OoRexx/negative-base-numbers.rexx
Normal file
59
Task/Negative-base-numbers/OoRexx/negative-base-numbers.rexx
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/* REXX ---------------------------------------------------------------
|
||||
* Adapt for ooRexx (use of now invalid variable names)
|
||||
* and make it work for base -63 (Algol example)
|
||||
*--------------------------------------------------------------------*/
|
||||
Numeric Digits 20
|
||||
digits='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz '
|
||||
txt=' converted to base '
|
||||
n= 10; b= -2; nb=nBase(n,b); Say right(n,20) txt right(b,3) '---->' nb ok()
|
||||
n= 146; b= -3; nb=nBase(n,b); Say right(n,20) txt right(b,3) '---->' nb ok()
|
||||
n= 15; b=-10; nb=nBase(n,b); Say right(n,20) txt right(b,3) '---->' nb ok()
|
||||
n= -15; b=-10; nb=nBase(n,b); Say right(n,20) txt right(b,3) '---->' nb ok()
|
||||
n= 0; b= -5; nb=nBase(n,b); Say right(n,20) txt right(b,3) '---->' nb ok()
|
||||
n=-6284695; b=-62; nb=nBase(n,b); Say right(n,20) txt right(b,3) '---->' nb ok()
|
||||
n=-36492107981104; b=-63;nb=nBase(n,b); Say right(n,20) txt right(b,3) '---->' nb ok()
|
||||
Exit
|
||||
|
||||
nBase: Procedure Expose digits
|
||||
/*---------------------------------------------------------------------
|
||||
* convert x (base 10) to result (base r)
|
||||
*--------------------------------------------------------------------*/
|
||||
Parse arg x,r
|
||||
result=''
|
||||
Do While x\==0 /*keep Processing while X isn't zero.*/
|
||||
z=x//r
|
||||
x=x%r /*calculate remainder; calculate int ÷.*/
|
||||
If z<0 Then Do
|
||||
z=z-r /*subtract a negative R from Z ?--+ */
|
||||
x=x+1 /*bump X by one. ¦ */
|
||||
End
|
||||
result=substr(digits,z+1,1)result /*prepend the new digit */
|
||||
End
|
||||
If result='' Then result=0
|
||||
Return result
|
||||
|
||||
pBase: Procedure Expose digits;
|
||||
/*---------------------------------------------------------------------
|
||||
* convert x (base r) to result (base 10)
|
||||
*--------------------------------------------------------------------*/
|
||||
Parse arg x,r;
|
||||
result=0;
|
||||
p=0
|
||||
len=length(x)
|
||||
Do j=len by -1 For len /*Process each of the X's digits */
|
||||
v=pos(substr(x,j,1),digits)-1 /*use digit's numeric value. */
|
||||
result=result+v*r**p; /*add it to result */
|
||||
p=p+1 /*bump power by 1 */
|
||||
End
|
||||
Return result
|
||||
|
||||
ok:
|
||||
/*---------------------------------------------------------------------
|
||||
* check back conversion
|
||||
*--------------------------------------------------------------------*/
|
||||
back=pBase(nb,b)
|
||||
If back\=n Then
|
||||
r='Error backward conversion results in' back
|
||||
Else
|
||||
r='ok'
|
||||
Return r
|
||||
37
Task/Negative-base-numbers/Perl/negative-base-numbers.pl
Normal file
37
Task/Negative-base-numbers/Perl/negative-base-numbers.pl
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
use strict;
|
||||
use feature 'say';
|
||||
use POSIX qw(floor);
|
||||
use ntheory qw/fromdigits todigits/;
|
||||
|
||||
sub encode {
|
||||
my($n, $b) = @_;
|
||||
my @out;
|
||||
my $r = 0;
|
||||
|
||||
while ($n) {
|
||||
$r = $n % $b;
|
||||
$n = floor $n/$b;
|
||||
$n += 1, $r -= $b if $r < 0;
|
||||
push @out, todigits($r, -$b) || 0;
|
||||
}
|
||||
join '', reverse @out;
|
||||
}
|
||||
|
||||
sub decode {
|
||||
my($s, $b) = @_;
|
||||
my $total = 0;
|
||||
my $i = 0;
|
||||
for my $c (reverse split '', $s) {
|
||||
$total += (fromdigits($c, -$b) * $b**$i);
|
||||
$i++;
|
||||
}
|
||||
$total
|
||||
}
|
||||
|
||||
say ' 10 in base -2: ', encode(10, -2);
|
||||
say ' 15 in base -10: ', encode(15, -10);
|
||||
say '146 in base -3: ', encode(146, -3);
|
||||
say '';
|
||||
say '11110 from base -2: ', decode("11110", -2);
|
||||
say '21102 from base -3: ', decode("21102", -3);
|
||||
say ' 195 from base -10: ', decode("195", -10);
|
||||
51
Task/Negative-base-numbers/Phix/negative-base-numbers.phix
Normal file
51
Task/Negative-base-numbers/Phix/negative-base-numbers.phix
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">digits</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"0123456789"</span><span style="color: #0000FF;">&</span>
|
||||
<span style="color: #008000;">"ABCDEFGHIJKLMNOPQRSTUVWXYZ"</span><span style="color: #0000FF;">&</span>
|
||||
<span style="color: #008000;">"abcdefghijklmnopqrstuvwxyz"</span>
|
||||
|
||||
<span style="color: #008080;">type</span> <span style="color: #000000;">base</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">b</span><span style="color: #0000FF;"><=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">and</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">>=-</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">digits</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">type</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">encodeNegBase</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">base</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">?</span><span style="color: #008000;">""</span><span style="color: #0000FF;">:</span><span style="color: #008000;">"0"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">while</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">trunc</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">/</span><span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">r</span><span style="color: #0000FF;"><</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">n</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #000000;">r</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">b</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">r</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">decodeNegBase</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">ns</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">base</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">total</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">bb</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ns</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ns</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">digits</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">=-</span><span style="color: #000000;">1</span> <span style="color: #008080;">or</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">>-</span><span style="color: #000000;">b</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #008000;">"invalid digit"</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">total</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">*</span><span style="color: #000000;">bb</span>
|
||||
<span style="color: #000000;">bb</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">b</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">total</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #000080;font-style:italic;">-- decimal, base, expected</span>
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"11110"</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">146</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"21102"</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">15</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"195"</span><span style="color: #0000FF;">},</span>
|
||||
<span style="color: #0000FF;">{-</span><span style="color: #000000;">5795577</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">62</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Phix"</span><span style="color: #0000FF;">}}</span>
|
||||
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #004080;">atom</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">e</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">ns</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">encodeNegBase</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%9d in base %-3d is %6s\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ns</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">nn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">decodeNegBase</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ns</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">ok</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ns</span><span style="color: #0000FF;">=</span><span style="color: #000000;">e</span> <span style="color: #008080;">and</span> <span style="color: #000000;">nn</span><span style="color: #0000FF;">=</span><span style="color: #000000;">n</span><span style="color: #0000FF;">?</span><span style="color: #008000;">""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" ????"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%9d <--------------'%s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">nn</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ok</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<!--
|
||||
43
Task/Negative-base-numbers/Python/negative-base-numbers.py
Normal file
43
Task/Negative-base-numbers/Python/negative-base-numbers.py
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
#!/bin/python
|
||||
from __future__ import print_function
|
||||
|
||||
def EncodeNegBase(n, b): #Converts from decimal
|
||||
if n == 0:
|
||||
return "0"
|
||||
out = []
|
||||
while n != 0:
|
||||
n, rem = divmod(n, b)
|
||||
if rem < 0:
|
||||
n += 1
|
||||
rem -= b
|
||||
out.append(rem)
|
||||
return "".join(map(str, out[::-1]))
|
||||
|
||||
def DecodeNegBase(nstr, b): #Converts to decimal
|
||||
if nstr == "0":
|
||||
return 0
|
||||
|
||||
total = 0
|
||||
for i, ch in enumerate(nstr[::-1]):
|
||||
total += int(ch) * b**i
|
||||
return total
|
||||
|
||||
if __name__=="__main__":
|
||||
|
||||
print ("Encode 10 as negabinary (expect 11110)")
|
||||
result = EncodeNegBase(10, -2)
|
||||
print (result)
|
||||
if DecodeNegBase(result, -2) == 10: print ("Converted back to decimal")
|
||||
else: print ("Error converting back to decimal")
|
||||
|
||||
print ("Encode 146 as negaternary (expect 21102)")
|
||||
result = EncodeNegBase(146, -3)
|
||||
print (result)
|
||||
if DecodeNegBase(result, -3) == 146: print ("Converted back to decimal")
|
||||
else: print ("Error converting back to decimal")
|
||||
|
||||
print ("Encode 15 as negadecimal (expect 195)")
|
||||
result = EncodeNegBase(15, -10)
|
||||
print (result)
|
||||
if DecodeNegBase(result, -10) == 15: print ("Converted back to decimal")
|
||||
else: print ("Error converting back to decimal")
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
[ dup dip /mod
|
||||
over iff
|
||||
[ - dip 1+ ]
|
||||
else drop ] is /mod+ ( n n --> n n )
|
||||
|
||||
[ over 0 = iff
|
||||
[ 2drop $ "0" ]
|
||||
done
|
||||
temp put
|
||||
$ "" swap
|
||||
[ temp share /mod+
|
||||
digit
|
||||
rot join swap
|
||||
dup 0 = until ]
|
||||
drop
|
||||
temp release ] is ->negabase$ ( n n --> $ )
|
||||
|
||||
[ over $ "0" = iff
|
||||
[ 2drop 0 ]
|
||||
done
|
||||
temp put
|
||||
0 swap
|
||||
witheach
|
||||
[ dip
|
||||
[ temp share * ]
|
||||
char->n + ]
|
||||
temp release ] is negabase$-> ( $ n --> n )
|
||||
|
||||
10 dup echo say " -> "
|
||||
-2 ->negabase$ dup echo$ say " -> "
|
||||
-2 negabase$-> echo cr
|
||||
146 dup echo say " -> "
|
||||
-3 ->negabase$ dup echo$ say " -> "
|
||||
-3 negabase$-> echo cr
|
||||
15 dup echo say " -> "
|
||||
-10 ->negabase$ dup echo$ say " -> "
|
||||
-10 negabase$-> echo cr
|
||||
29
Task/Negative-base-numbers/REXX/negative-base-numbers-1.rexx
Normal file
29
Task/Negative-base-numbers/REXX/negative-base-numbers-1.rexx
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*REXX pgm converts & displays a base ten integer to a negative base number (up to -10).*/
|
||||
@=' converted to base '; numeric digits 300 /*be able to handle ginormous numbers. */
|
||||
n= 10; b= -2; q= nBase(n, b); say right(n, 20) @ right(b, 3) '────►' q ok()
|
||||
n= 146; b= -3; q= nBase(n, b); say right(n, 20) @ right(b, 3) '────►' q ok()
|
||||
n= 15; b= -10; q= nBase(n, b); say right(n, 20) @ right(b, 3) '────►' q ok()
|
||||
n= -15; b= -10; q= nBase(n, b); say right(n, 20) @ right(b, 3) '────►' q ok()
|
||||
n= 0; b= -5; q= nBase(n, b); say right(n, 20) @ right(b, 3) '────►' q ok()
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
nBase: procedure; parse arg x,r; $= /*obtain args; $ is the integer result.*/
|
||||
if r<-10 | r>-2 then do; say 'base' r "must be in range: -2 ───► -10"; exit 13; end
|
||||
do while x\==0 /*keep processing while X isn't zero.*/
|
||||
z= x // r; x= x % r /*calculate remainder; calculate int ÷.*/
|
||||
if z<0 then do; z= z - r /*subtract a negative R from Z ◄──┐ */
|
||||
x= x + 1 /*bump X by one. │ */
|
||||
end /* Funny "add" ►───┘ */
|
||||
$= z || $ /*prepend new digit (numeral) to result*/
|
||||
end /*while*/
|
||||
return word($ 0, 1) /*possibly adjust for a zero value. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
ok: ?=; if pBase(q, b)\=n then ?= ' ◄──error in negative base calculation'; return ?
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
pBase: procedure; parse arg x,r; p= 0; $= 0 /*obtain args; $ is the integer result.*/
|
||||
if r<-10 | r>-2 then do; say 'base' r "must be in range: -2 ───► -10"; exit 13; end
|
||||
do j=length(x) by -1 for length(x) /*process each of the numerals in X. */
|
||||
$= $ + substr(x,j,1) * r ** p /*add value of a numeral to $ (result).*/
|
||||
p= p + 1 /*bump the power by 1. */
|
||||
end /*j*/ /* [↓] process the number "bottom-up".*/
|
||||
return $
|
||||
33
Task/Negative-base-numbers/REXX/negative-base-numbers-2.rexx
Normal file
33
Task/Negative-base-numbers/REXX/negative-base-numbers-2.rexx
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
/*REXX pgm converts & displays a base ten integer to a negative base number (up to -71).*/
|
||||
@=' converted to base '; numeric digits 300 /*be able to handle ginormous numbers. */
|
||||
n= 10; b= -2; q= nBase(n, b); say right(n, 20) @ right(b,3) '────►' q ok()
|
||||
n= 146; b= -3; q= nBase(n, b); say right(n, 20) @ right(b,3) '────►' q ok()
|
||||
n= 15; b= -10; q= nBase(n, b); say right(n, 20) @ right(b,3) '────►' q ok()
|
||||
n= -15; b= -10; q= nBase(n, b); say right(n, 20) @ right(b,3) '────►' q ok()
|
||||
n= 0; b= -5; q= nBase(n, b); say right(n, 20) @ right(b,3) '────►' q ok()
|
||||
n=-6284695; b= -62; q= nBase(n, b); say right(n, 20) @ right(b,3) '────►' q ok()
|
||||
exit /*stick a fork in it, we're all done. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
_Base: !='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz /*+-!éáµ' /*sym*/
|
||||
parse arg $; m= length(!); L= length(x); p= 0
|
||||
if r<-m | r>-2 then do; say 'base' r "must be in range: -2 ───► -"m; exit 13; end
|
||||
return
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
nBase: procedure; parse arg x,r; call _Base /*get args; $ will be integer result. */
|
||||
do while x\==0 /*keep processing while X isn't zero.*/
|
||||
z=x // r; x= x % r /*calculate remainder; calculate int ÷.*/
|
||||
if z<0 then do; z= z - r /*subtract a negative R from Z ◄──┐ */
|
||||
x= x + 1 /*bump X by one. │ */
|
||||
end /* Funny "add" ►───┘ */
|
||||
$=substr(!, z+1, 1)$ /*prepend the new numeral to the result*/
|
||||
end /*while*/
|
||||
if $=='' then return 0; return $ /*possibly adjust for a zero value. */
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
ok: if pBase(q, b)\=n then return ' ◄──error in negative base calculation'; return ''
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
pBase: procedure; parse arg x,r; call _Base 0 /*get args; $ will be integer result. */
|
||||
do j=L by -1 for L /*process each of the numerals in X. */
|
||||
v=pos( substr(x,j,1), !) - 1 /*use base R for the numeral's value.*/
|
||||
$= $ + v * r**p; p= p + 1 /*add it to $ (result); bump power by 1*/
|
||||
end /*j*/ /* [↑] process the number "bottom-up".*/
|
||||
return $
|
||||
59
Task/Negative-base-numbers/Racket/negative-base-numbers.rkt
Normal file
59
Task/Negative-base-numbers/Racket/negative-base-numbers.rkt
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
#lang racket
|
||||
|
||||
(define all-digits (string->list "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-"))
|
||||
|
||||
(define d->i-map (for/hash ((i (in-naturals)) (d all-digits)) (values d i)))
|
||||
|
||||
(define max-base (length all-digits))
|
||||
|
||||
(define (q/r n d)
|
||||
(let-values (((q r) (quotient/remainder n d)))
|
||||
(if (negative? r)
|
||||
(values (+ q 1) (- r d))
|
||||
(values q r))))
|
||||
|
||||
(define (negabase-convertors base)
|
||||
(when (not (integer? base)) (raise "Non-integer base."))
|
||||
(when (not (<= 2 (abs base) max-base)) (raise (format "(abs base) must be inside [2 ~a] interval." max-base)))
|
||||
(values
|
||||
(let ((q/r_base (curryr q/r base)))
|
||||
(λ (num)
|
||||
(define (checked->base num dig)
|
||||
(match num
|
||||
[0 (apply string dig)]
|
||||
[(app q/r_base num/ rst) (checked->base num/ (cons (list-ref all-digits rst) dig))]))
|
||||
(if (integer? num)
|
||||
(checked->base num (if (zero? num) '(#\0) '()))
|
||||
(raise "Non-integer number."))))
|
||||
|
||||
(λ (dig)
|
||||
(define (loop digs acc)
|
||||
(match digs [(list) acc] [(cons a d) (loop d (+ (* acc base) (hash-ref d->i-map a)))]))
|
||||
(loop (string->list dig) 0))))
|
||||
|
||||
(define-values (->negabinary negabinary->) (negabase-convertors -2))
|
||||
|
||||
(define-values (->negaternary negaternary->) (negabase-convertors -3))
|
||||
|
||||
(define-values (->negadecimal negadecimal->) (negabase-convertors -10))
|
||||
|
||||
(define-values (->nega63ary nega63ary->) (negabase-convertors (- max-base)))
|
||||
|
||||
(module+ main
|
||||
(->negaternary 146)
|
||||
(->negabinary 10)
|
||||
(->negadecimal 15)
|
||||
(->nega63ary -26238001742))
|
||||
|
||||
(module+ test
|
||||
(require rackunit)
|
||||
|
||||
;; tests from wikipedia page
|
||||
(check-equal? (call-with-values (λ () (q/r 146 -3)) cons) '(-48 . 2))
|
||||
(check-equal? (call-with-values (λ () (q/r -48 -3)) cons) '(16 . 0))
|
||||
(check-equal? (call-with-values (λ () (q/r 16 -3)) cons) '(-5 . 1))
|
||||
(check-equal? (call-with-values (λ () (q/r -5 -3)) cons) '(2 . 1))
|
||||
(check-equal? (call-with-values (λ () (q/r 2 -3)) cons) '(0 . 2))
|
||||
|
||||
(define-values (->hexadecimal hexadecimal->) (negabase-convertors 16))
|
||||
(check-equal? (->hexadecimal 31) "1F"))
|
||||
52
Task/Negative-base-numbers/Raku/negative-base-numbers-1.raku
Normal file
52
Task/Negative-base-numbers/Raku/negative-base-numbers-1.raku
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
multi sub base ( Int $value is copy, Int $radix where -37 < * < -1) {
|
||||
my $result;
|
||||
while $value {
|
||||
my $r = $value mod $radix;
|
||||
$value div= $radix;
|
||||
if $r < 0 {
|
||||
$value++;
|
||||
$r -= $radix
|
||||
}
|
||||
$result ~= $r.base(-$radix);
|
||||
}
|
||||
flip $result || ~0;
|
||||
}
|
||||
|
||||
multi sub base ( Real $num, Int $radix where -37 < * < -1, :$precision = -15 ) {
|
||||
return '0' unless $num;
|
||||
my $value = $num;
|
||||
my $result = '';
|
||||
my $place = 0;
|
||||
my $upper-bound = 1 / (-$radix + 1);
|
||||
my $lower-bound = $radix * $upper-bound;
|
||||
|
||||
$value = $num / $radix ** ++$place until $lower-bound <= $value < $upper-bound;
|
||||
|
||||
while ($value or $place > 0) and $place > $precision {
|
||||
my $digit = ($radix * $value - $lower-bound).Int;
|
||||
$value = $radix * $value - $digit;
|
||||
$result ~= '.' unless $place or $result.contains: '.';
|
||||
$result ~= $digit == -$radix ?? ($digit-1).base(-$radix)~'0' !! $digit.base(-$radix);
|
||||
$place--
|
||||
}
|
||||
$result
|
||||
}
|
||||
|
||||
multi sub parse-base (Str $str, Int $radix where -37 < * < -1) {
|
||||
return -1 * $str.substr(1).&parse-base($radix) if $str.substr(0,1) eq '-';
|
||||
my ($whole, $frac) = $str.split: '.';
|
||||
my $fraction = 0;
|
||||
$fraction = [+] $frac.comb.kv.map: { $^v.parse-base(-$radix) * $radix ** -($^k+1) } if $frac;
|
||||
$fraction + [+] $whole.flip.comb.kv.map: { $^v.parse-base(-$radix) * $radix ** $^k }
|
||||
}
|
||||
|
||||
# TESTING
|
||||
for <4 -4 0 -7 10 -2 146 -3 15 -10 -19 -10 107 -16
|
||||
227.65625 -16 2.375 -4 -1.3e2 -8 41371457.268272761 -36> -> $v, $r {
|
||||
my $nbase = $v.&base($r, :precision(-5));
|
||||
printf "%20s.&base\(%3d\) = %-11s : %13s.&parse-base\(%3d\) = %s\n",
|
||||
$v, $r, $nbase, "'$nbase'", $r, $nbase.&parse-base($r);
|
||||
}
|
||||
|
||||
# 'Illegal' negative-base value
|
||||
say q| '-21'.&parse-base(-10) = |, '-21'.&parse-base(-10);
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
use Base::Any;
|
||||
|
||||
for < 4 -4 0 -7 10 -2 146 -3 15 -10 -19 -10 107 -16
|
||||
227.65625 -16 2.375 -4 -1.3e2 -8 41371457.268272761 -36
|
||||
-145115966751439403/3241792 -1184 > -> $v, $r {
|
||||
my $nbase = $v.&to-base($r, :precision(-5));
|
||||
printf "%21s.&to-base\(%5d\) = %-11s : %13s.&from-base\(%5d\) = %s\n",
|
||||
+$v, $r, $nbase, "'$nbase'", $r, $nbase.&from-base($r);
|
||||
}
|
||||
39
Task/Negative-base-numbers/Ring/negative-base-numbers.ring
Normal file
39
Task/Negative-base-numbers/Ring/negative-base-numbers.ring
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# Project : Negative base numbers
|
||||
|
||||
negs = [[146,-3],[21102,-3],[10,-2],[11110,-2],[15,-10],[195,-10]]
|
||||
for n = 1 to len(negs) step 2
|
||||
enc = encodeNegBase(negs[n][1],negs[n][2])
|
||||
encstr = showarray(enc)
|
||||
dec = decodeNegBase(negs[n+1][1],negs[n+1][2])
|
||||
see "" + negs[n][1] + " encoded in base " + negs[n][2] + " = " + encstr + nl
|
||||
see "" + negs[n+1][1] + " decoded in base " + negs[n+1][2] + " = " + dec + nl
|
||||
next
|
||||
|
||||
func encodeNegBase(n,b)
|
||||
out = []
|
||||
while n != 0
|
||||
rem = (n%b)
|
||||
if rem < 0
|
||||
rem = rem - b
|
||||
ok
|
||||
n = ceil(n/b)
|
||||
rem = fabs(rem)
|
||||
add(out,rem)
|
||||
end
|
||||
out = reverse(out)
|
||||
return out
|
||||
|
||||
func decodeNegBase(n,b)
|
||||
out = 0
|
||||
n = string(n)
|
||||
for nr = len(n) to 1 step -1
|
||||
out = out + n[nr]*pow(b,len(n)-nr)
|
||||
next
|
||||
return out
|
||||
|
||||
func showarray(vect)
|
||||
svect = ""
|
||||
for n = 1 to len(vect)
|
||||
svect = svect + vect[n]
|
||||
next
|
||||
return svect
|
||||
39
Task/Negative-base-numbers/Ruby/negative-base-numbers.rb
Normal file
39
Task/Negative-base-numbers/Ruby/negative-base-numbers.rb
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
DIGITS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'
|
||||
|
||||
# convert a base 10 integer into a negative base value (as a string)
|
||||
|
||||
def negative_base_encode(n, b)
|
||||
raise 'base out of range' if (b < -62) || (b > -2)
|
||||
return '0' if n == 0
|
||||
revdigs = []
|
||||
while n != 0 do
|
||||
n, r = n.divmod(b)
|
||||
if r < 0
|
||||
n += 1
|
||||
r -= b
|
||||
end
|
||||
revdigs << r
|
||||
end
|
||||
return revdigs.reduce('') { |digstr, digit| DIGITS[digit] + digstr }
|
||||
end
|
||||
|
||||
# convert a negative base value (as a string) into a base 10 integer
|
||||
|
||||
def negative_base_decode(n, b)
|
||||
raise 'base out of range' if (b < -62) || (b > -2)
|
||||
value = 0
|
||||
n.reverse.each_char.with_index do |ch, inx|
|
||||
value += DIGITS.index(ch) * b**inx
|
||||
end
|
||||
return value
|
||||
end
|
||||
|
||||
# do the task
|
||||
|
||||
[ [10, -2], [146, -3], [15, -10], [0, -31], [-6221826, -62] ].each do |pair|
|
||||
decimal, base = pair
|
||||
encoded = negative_base_encode(decimal, base)
|
||||
decoded = negative_base_decode(encoded, base)
|
||||
puts("Enc: %8i base %-3i = %5s base %-3i Dec: %5s base %-3i = %8i base %-3i" %
|
||||
[decimal, 10, encoded, base, encoded, base, decoded, 10])
|
||||
end
|
||||
49
Task/Negative-base-numbers/Rust/negative-base-numbers.rust
Normal file
49
Task/Negative-base-numbers/Rust/negative-base-numbers.rust
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
const DIGITS: [char;62] = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
|
||||
|
||||
|
||||
fn main() {
|
||||
let nums_and_bases: [(i64,i64);5] = [(10,-2),(146,-3),(15,-10),(-6222885,-62),(1488588316238,-62)];
|
||||
|
||||
for (n,b) in nums_and_bases.iter() {
|
||||
let ns = encode_neg_base(*n, *b);
|
||||
println!("{} encoded in base {} = {}", *n, *b, &ns);
|
||||
let nn = decode_neg_base(&ns, *b);
|
||||
println!("{} decoded in base {} = {}\n", &ns, *b, nn);
|
||||
}
|
||||
}
|
||||
|
||||
fn decode_neg_base(ns: &str, b: i64) -> i64 {
|
||||
if b < -62 || b > -1 {
|
||||
panic!("base must be between -62 and -1 inclusive")
|
||||
}
|
||||
if ns == "0" {
|
||||
return 0
|
||||
}
|
||||
let mut total: i64 = 0;
|
||||
let mut bb: i64 = 1;
|
||||
for c in ns.chars().rev() {
|
||||
total += (DIGITS.iter().position(|&d| d==c).unwrap() as i64) * bb;
|
||||
bb *= b;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
fn encode_neg_base(mut n: i64, b: i64) -> String {
|
||||
if b < -62 || b > -1 {
|
||||
panic!("base must be between -62 and -1 inclusive");
|
||||
}
|
||||
if n == 0 {
|
||||
return "0".to_string();
|
||||
}
|
||||
let mut out = String::new();
|
||||
while n != 0 {
|
||||
let mut rem = n % b;
|
||||
n /= b;
|
||||
if rem < 0 {
|
||||
n+=1;
|
||||
rem -= b;
|
||||
}
|
||||
out.push(DIGITS[rem as usize]);
|
||||
}
|
||||
return out.chars().rev().collect();
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
object NegativeBase {
|
||||
val digits = ('0' to '9') ++ ('a' to 'z') ++ ('A' to 'Z')
|
||||
|
||||
def intToStr(n: Int, b: Int): String = {
|
||||
def _fromInt(n: Int): List[Int] = {
|
||||
if (n == 0) {
|
||||
Nil
|
||||
} else {
|
||||
val r = n % b
|
||||
val rp = if (r < 0) r + b else r
|
||||
val m = -(n - rp)/b
|
||||
rp :: _fromInt(m)
|
||||
}
|
||||
}
|
||||
_fromInt(n).map(digits).reverse.mkString
|
||||
}
|
||||
|
||||
def strToInt(s: String, b: Int): Int = {
|
||||
s.map(digits.indexOf).foldRight((0, 1)){ case (x, (sum, pow)) =>
|
||||
(sum + x * pow, pow * -b)
|
||||
}._1
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
def testConversion(b: Int)(n: Int, s: String): Unit = {
|
||||
println(s"$n in base -$b = ${NegativeBase.intToStr(n, b)}")
|
||||
println(s"$s from base -$b = ${NegativeBase.strToInt(s, b)}")
|
||||
}
|
||||
|
||||
testConversion(2)(10, "11110")
|
||||
testConversion(3)(146, "21102")
|
||||
testConversion(10)(15, "195")
|
||||
testConversion(62)(795099356, "Scala")
|
||||
71
Task/Negative-base-numbers/Seed7/negative-base-numbers.seed7
Normal file
71
Task/Negative-base-numbers/Seed7/negative-base-numbers.seed7
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
$ include "seed7_05.s7i";
|
||||
|
||||
const string: DIGITS is "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
const func string: encodeNegativeBase (in var integer: number, in integer: base) is func
|
||||
result
|
||||
var string: encoded is "";
|
||||
local
|
||||
var integer: remainder is 0;
|
||||
begin
|
||||
if base < -62 or base > -1 then
|
||||
raise RANGE_ERROR;
|
||||
elsif number = 0 then
|
||||
encoded := "0";
|
||||
else
|
||||
while number <> 0 do
|
||||
remainder := number rem base;
|
||||
number := number div base;
|
||||
if remainder < 0 then
|
||||
incr(number);
|
||||
remainder -:= base;
|
||||
end if;
|
||||
encoded &:= DIGITS[succ(remainder)];
|
||||
end while;
|
||||
encoded := reverse(encoded);
|
||||
end if;
|
||||
end func;
|
||||
|
||||
const func integer: decodeNegativeBase (in string: encoded, in integer: base) is func
|
||||
result
|
||||
var integer: decoded is 0;
|
||||
local
|
||||
var integer: factor is 1;
|
||||
var integer: index is 0;
|
||||
var integer: digit is 0;
|
||||
begin
|
||||
if base < -62 or base > -1 then
|
||||
raise RANGE_ERROR;
|
||||
elsif encoded = "0" then
|
||||
decoded := 0;
|
||||
else
|
||||
for index range length(encoded) downto 1 do
|
||||
digit := pred(pos(DIGITS, encoded[index]));
|
||||
if digit = -1 then
|
||||
raise RANGE_ERROR;
|
||||
else
|
||||
decoded +:= digit * factor;
|
||||
factor *:= base;
|
||||
end if;
|
||||
end for;
|
||||
end if;
|
||||
end func;
|
||||
|
||||
const proc: doCheck (in integer: number, in integer: base) is func
|
||||
local
|
||||
var string: encoded is "";
|
||||
var integer: decoded is 0;
|
||||
begin
|
||||
encoded := encodeNegativeBase(number, base);
|
||||
writeln(number lpad 10 <& " encoded in base " <& base lpad 3 <& " = " <& encoded);
|
||||
decoded := decodeNegativeBase(encoded, base);
|
||||
writeln(encoded lpad 10 <& " decoded in base " <& base lpad 3 <& " = " <& decoded);
|
||||
end func;
|
||||
|
||||
const proc: main is func
|
||||
begin
|
||||
doCheck(10, -2);
|
||||
doCheck(146, -3);
|
||||
doCheck(15, -10);
|
||||
doCheck(404355637, -62);
|
||||
end func;
|
||||
37
Task/Negative-base-numbers/Sidef/negative-base-numbers.sidef
Normal file
37
Task/Negative-base-numbers/Sidef/negative-base-numbers.sidef
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
func EncodeNegBase(Num n, Num b { .~~ (-36 .. -2) }) {
|
||||
var out = []
|
||||
var r = 0
|
||||
while (n) {
|
||||
(n, r) = divmod(n, b)
|
||||
if (r < 0) {
|
||||
n += 1
|
||||
r -= b
|
||||
}
|
||||
out << r.base(-b)
|
||||
}
|
||||
return (out.join.flip || "0")
|
||||
}
|
||||
|
||||
func DecodeNegBase(Str s, Num b { .~~ (-36 .. -2) }) {
|
||||
var total = 0
|
||||
for i,c in (s.flip.chars.kv) {
|
||||
total += (Num(c, -b) * b**i)
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
say (" 10 in base -2: ", EncodeNegBase(10, -2))
|
||||
say ("146 in base -3: ", EncodeNegBase(146, -3))
|
||||
say (" 15 in base -10: ", EncodeNegBase(15, -10))
|
||||
|
||||
say '-'*25
|
||||
|
||||
say ("11110 from base -2: ", DecodeNegBase("11110", -2))
|
||||
say ("21102 from base -3: ", DecodeNegBase("21102", -3))
|
||||
say (" 195 from base -10: ", DecodeNegBase("195", -10))
|
||||
|
||||
say '-'*25
|
||||
|
||||
# Extra
|
||||
say ("25334424 in base -31: ", EncodeNegBase(25334424, -31))
|
||||
say ("sidef from base -31: ", DecodeNegBase("sidef", -31))
|
||||
66
Task/Negative-base-numbers/VBA/negative-base-numbers.vba
Normal file
66
Task/Negative-base-numbers/VBA/negative-base-numbers.vba
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
Const DIGITS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
Dim Str(63) As String
|
||||
Private Function mod2(a As Long, b As Integer) As Long
|
||||
mod2 = a - (a \ b) * b
|
||||
End Function
|
||||
Private Function swap(a As String, b As String)
|
||||
Dim t As String
|
||||
t = a
|
||||
a = b
|
||||
b = t
|
||||
End Function
|
||||
Private Function EncodeNegativeBase(ByVal n As Long, base As Integer) As String
|
||||
Dim ptr, idx As Long
|
||||
Dim rem_ As Long
|
||||
Dim result As String
|
||||
If base > -1 Or base < -62 Then
|
||||
EncodeNegativeBase = result
|
||||
Else
|
||||
If n = 0 Then
|
||||
EncodeNegativeBase = "0"
|
||||
Else
|
||||
ptr = 0
|
||||
Do While n <> 0
|
||||
rem_ = mod2(n, base)
|
||||
n = n \ base
|
||||
If rem_ < 0 Then
|
||||
n = n + 1
|
||||
rem_ = rem_ - base
|
||||
End If
|
||||
result = result & Mid(DIGITS, rem_ + 1, 1)
|
||||
Loop
|
||||
End If
|
||||
End If
|
||||
EncodeNegativeBase = StrReverse(result)
|
||||
End Function
|
||||
Private Function DecodeNegativeBase(ns As String, base As Integer) As Long
|
||||
Dim total As Long, bb As Long
|
||||
Dim i As Integer, j As Integer
|
||||
If base < -62 Or base > -1 Then DecodeNegativeBase = 0
|
||||
If Mid(ns, 1, 1) = 0 Or (Mid(ns, 1, 1) = "0" And Mid(ns, 2, 1) = 0) Then DecodeNegativeBase = 0
|
||||
i = Len(ns)
|
||||
total = 0
|
||||
bb = 1
|
||||
Do While i >= 1
|
||||
j = InStr(1, DIGITS, Mid(ns, i, 1), vbTextCompare) - 1
|
||||
total = total + j * bb
|
||||
bb = bb * base
|
||||
i = i - 1
|
||||
Loop
|
||||
DecodeNegativeBase = total
|
||||
End Function
|
||||
Private Sub Driver(n As Long, b As Integer)
|
||||
Dim ns As String
|
||||
Dim p As Long
|
||||
ns = EncodeNegativeBase(n, b)
|
||||
Debug.Print CStr(n); " encoded in base "; b; " = "; ns
|
||||
p = DecodeNegativeBase(ns, b)
|
||||
Debug.Print ns; " decoded in base "; b; " = "; p
|
||||
Debug.Print
|
||||
End Sub
|
||||
Public Sub main()
|
||||
Driver 10, -2
|
||||
Driver 146, -3
|
||||
Driver 15, -10
|
||||
Driver 118492, -62
|
||||
End Sub
|
||||
39
Task/Negative-base-numbers/Wren/negative-base-numbers.wren
Normal file
39
Task/Negative-base-numbers/Wren/negative-base-numbers.wren
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import "/fmt" for Fmt
|
||||
|
||||
var digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
var encodeNegBase = Fn.new { |n, b|
|
||||
if (b < -62 || b > -1) Fiber.abort("Base must be between -1 and -62")
|
||||
if (n == 0) return "0"
|
||||
var out = ""
|
||||
while (n != 0) {
|
||||
var rem = n % b
|
||||
n = (n/b).truncate
|
||||
if (rem < 0) {
|
||||
n = n + 1
|
||||
rem = rem -b
|
||||
}
|
||||
out = out + digits[rem]
|
||||
}
|
||||
return out[-1..0]
|
||||
}
|
||||
|
||||
var decodeNegBase = Fn.new { |ns, b|
|
||||
if (b < -62 || b > -1) Fiber.abort("Base must be between -1 and -62")
|
||||
if (ns == "0") return 0
|
||||
var total = 0
|
||||
var bb = 1
|
||||
for (c in ns[-1..0]) {
|
||||
total = total + digits.indexOf(c)*bb
|
||||
bb = bb * b
|
||||
}
|
||||
return total
|
||||
}
|
||||
|
||||
var nbl = [ [10, -2], [146, -3], [15, -10], [-7425195, -62] ]
|
||||
for (p in nbl) {
|
||||
var ns = encodeNegBase.call(p[0], p[1])
|
||||
Fmt.print("$8d encoded in base $-3d = $s", p[0], p[1], ns)
|
||||
var n = decodeNegBase.call(ns, p[1])
|
||||
Fmt.print("$8s decoded in base $-3d = $d\n", ns, p[1], n)
|
||||
}
|
||||
15
Task/Negative-base-numbers/Zkl/negative-base-numbers-1.zkl
Normal file
15
Task/Negative-base-numbers/Zkl/negative-base-numbers-1.zkl
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
fcn toNBase(n,radix){
|
||||
var [const] cs=[0..9].chain(["a".."z"]).pump(String); //"0123456789abcd..z"
|
||||
_assert_(-37 < radix < -1,"invalid radix");
|
||||
digits:=List();
|
||||
while(n){ reg r;
|
||||
n,r=n.divr(radix); // C compiler semantics
|
||||
if(r<0){ n+=1; r-=radix; }
|
||||
digits.append(r);
|
||||
}
|
||||
digits.reverse().pump(String,cs.get);
|
||||
}
|
||||
|
||||
fcn toInt(str,radix){ // the toInt(radix) method radix is 2..36
|
||||
str.reduce('wrap(s,d,rdx){ s*radix + d.toInt(rdx); },0,radix.abs());
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
ns:=T( T(10,-2), T(146,-3), T(15,-10), T(107,-16), T(41371458,-36), T(44661,-36) );
|
||||
results:=ns.pump(List,Void.Xplode,toNBase);
|
||||
foreach nb,r in (ns.zip(results)){
|
||||
_,b:=nb;
|
||||
println("%10d.base(%3d) = \"%s\" --> %d".fmt(nb.xplode(),r,toInt(r,b)));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue