मनमाना आधार रूपांतरण [बंद]


10

एक रूटीन बनाएं जो एक संख्यात्मक आधार प्रणाली में ब्लॉक की एक सरणी लेता है, और उन्हें अन्य संख्यात्मक आधार प्रणाली में ब्लॉक के एक सरणी में परिवर्तित करता है। दोनों से और सिस्टम से मनमानी होती है और इसे एक पैरामीटर के रूप में स्वीकार किया जाना चाहिए। इनपुट सरणी एक मनमानी लंबाई हो सकती है (यदि ऐसी भाषा का उपयोग करना जहां सरणी लंबाई सरणी के साथ संग्रहीत नहीं है, जैसे कि सी, एक लंबाई पैरामीटर फ़ंक्शन को पास किया जाना चाहिए)।

यहां बताया गया है कि यह कैसे काम करना चाहिए:

fromArray = [1, 1]
fromBase = 256
toBase = 16
result = convertBase(fromArray, fromBase, toBase);

जो लौटाना चाहिए [0, 1, 0, 1]या संभावित रूप से [1, 0, 1](अग्रणी 0s वैकल्पिक हैं क्योंकि वे उत्तर का मूल्य नहीं बदलते हैं)।

यहाँ कुछ परीक्षण वैक्टर हैं:

  1. आइडेंटिटी टेस्ट वेक्टर

    fromArray = [1, 2, 3, 4]
    fromBase = 16
    toBase = 16
    result = [1, 2, 3, 4]
    
  2. ट्रिवियल टेस्ट वेक्टर

    fromArray = [1, 0]
    fromBase = 10
    toBase = 100
    result = [10]
    
  3. बड़ा टेस्ट वेक्टर

    fromArray = [41, 15, 156, 123, 254, 156, 141, 2, 24]
    fromBase = 256
    toBase = 16
    result = [2, 9, 0, 15, 9, 12, 7, 11, 15, 14, 9, 12, 8, 13, 0, 2, 1, 8]
    
  4. रियली बिग टेस्ट वेक्टर

    fromArray = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
    fromBase = 2
    toBase = 10
    result = [1, 2, 3, 7, 9, 4, 0, 0, 3, 9, 2, 8, 5, 3, 8, 0, 2, 7, 4, 8, 9, 9, 1, 2, 4, 2, 2, 3]
    
  5. नॉन-बेस बेस वेक्टर

    fromArray = [41, 42, 43]
    fromBase = 256
    toBase = 36
    result = [1, 21, 29, 22, 3]
    

अन्य मानदंड / नियम:

  1. सभी पूर्णांक चर सभी साने इनपुट श्रेणियों के लिए एक मानक 32 बिट हस्ताक्षरित पूर्णांक के भीतर फिट होने चाहिए।

  2. आप एक मध्यस्थ प्रतिनिधित्व में परिवर्तित कर सकते हैं, जब तक कि मध्यस्थ 32 बिट हस्ताक्षरित पूर्णांकों की एक सरणी से अधिक कुछ नहीं है।

  3. 256 के माध्यम से 2 से अड्डों को संभालने की अपेक्षा करें। इससे अधिक आधारों का समर्थन करने की कोई आवश्यकता नहीं है (लेकिन यदि आप हर तरह से चाहते हैं)।

  4. कम से कम 1000 तत्वों तक इनपुट और आउटपुट आकार को संभालने की अपेक्षा करें । एक समाधान जो 2 ^ 32-1 तत्वों के लिए तराजू बेहतर होगा, लेकिन 1000 बस ठीक है।

  5. यह जरूरी नहीं कि सबसे छोटा कोड हो जो इन नियमों को पूरा करेगा। यह सबसे साफ और सबसे सुंदर कोड होने के बारे में है।

अब, यह करने के लिए बिल्कुल तुच्छ नहीं है, इसलिए एक जवाब जो लगभग काम करता है स्वीकार किया जा सकता है!


क्या # 1 का मतलब है कि हम एक बड़े प्रकार का उपयोग नहीं कर सकते हैं?
कीथ रान्डेल

@ कीथ: सही है। केवल 32 बिट पूर्णांक।
ircmaxell

आप कहते हैं "हस्ताक्षरित पूर्णांक" लेकिन उदाहरण केवल सकारात्मक पूर्णांक के लिए हैं, इसलिए: क्या हमें नकारात्मक को संभालना है?
रात 12'11

@ बारह: मैं नकारात्मक को संभालने की जरूरत नहीं देखता। यदि एक नकारात्मक नियंत्रित किया जाता है, तो यह कनवर्टर के बाहर होगा।
ircmaxell

क्या वे हमेशा पूर्णांक आधार हैं?
पीटर ओल्सन

जवाबों:


8

अजगर

# divides longnum src (in base src_base) by divisor
# returns a pair of (longnum dividend, remainder)
def divmod_long(src, src_base, divisor):
  dividend=[]
  remainder=0
  for d in src:
    (e, remainder) = divmod(d + remainder * src_base, divisor)
    if dividend or e: dividend += [e]
  return (dividend, remainder)

def convert(src, src_base, dst_base):
  result = []
  while src:
    (src, remainder) = divmod_long(src, src_base, dst_base)
    result = [remainder] + result
  return result

धन्यवाद। मैं इस तरह एक रूटीन की तलाश में था। हालाँकि इसे जावास्क्रिप्ट में बदलने में मुझे थोड़ा समय लगा। मैं शायद इसे थोड़ा गोल्फ करूँगा और इसके मज़े के लिए यहाँ पोस्ट करूँगा।
स्टीफन पेरेलसन

5

यहाँ एक हास्केल समाधान है

import Data.List
import Control.Monad

type Numeral = (Int, [Int])

swap              ::  (a,b) -> (b,a)
swap (x,y)        =   (y,x)

unfoldl           ::  (b -> Maybe (b,a)) -> b -> [a]
unfoldl f         =   reverse . unfoldr (fmap swap . f)

normalize         ::  Numeral -> Numeral
normalize (r,ds)  =   (r, dropWhile (==0) ds)

divModLongInt            ::  Numeral -> Int -> (Numeral,Int)
divModLongInt (r,dd) dv  =   let  divDigit c d = swap ((c*r+d) `divMod` dv)
                                  (remainder, quotient) = mapAccumR divDigit 0 (reverse dd)
                             in   (normalize (r,reverse quotient), remainder)

changeRadixLongInt       ::  Numeral -> Int -> Numeral
changeRadixLongInt n r'  =   (r', unfoldl produceDigit n)
  where  produceDigit  (_,[])   =  Nothing
         produceDigit  x        =  Just (divModLongInt x r')

changeRadix :: [Int] -> Int -> Int -> [Int]
changeRadix digits origBase newBase = snd $ changeRadixLongInt (origBase,digits) newBase

doLine line = let [(digits,rest0)] = reads line
                  [(origBase,rest1)] = reads rest0
                  [(newBase,rest2)] = reads rest1
              in show $ changeRadix digits origBase newBase

main = interact (unlines . map doLine . lines)

और प्रश्न से परीक्षण चल रहा है:

$ ./a.out 
[1,2,3,4] 16 16
[1,2,3,4]
[1,0] 10 100
[10]
[41, 15, 156, 123, 254, 156, 141, 2, 24] 256 16
[2,9,0,15,9,12,7,11,15,14,9,12,8,13,0,2,1,8]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1] 2 10
[1,2,3,7,9,4,0,0,3,9,2,8,5,3,8,0,2,7,4,8,9,9,1,2,4,2,2,3]
[41, 42, 43] 256 36
[1,21,29,22,3]

ओह वाह। वह तो कमाल है! अब, अगर केवल मैं इसे समझ सकता था: -) ... (लेकिन यह अब मेरा काम है) ...
ircmaxell

5

आर

संभालती तत्वों के कई हजारों * एक मिनट से भी कम समय में।

addb <- function(v1,v2,b) {
    ml <- max(length(v1),length(v2))
    v1 <- c(rep(0, ml-length(v1)),v1)
    v2 <- c(rep(0, ml-length(v2)),v2)
    v1 = v1 + v2
    resm = v1%%b
    resd = c(floor(v1/b),0)
    while (any(resd != 0)) {
        v1 = c(0,resm) + resd
        resm = v1%%b
        resd = c(floor(v1/b),0)
    }
    while (v1[1] == 0) v1 = v1[-1]
    return(v1)
}

redb <- function(v,b) {
    return (addb(v,0,b))
}

mm = rbind(1)

mulmat <- function(fromb, tob, n) {
    if (dim(mm)[2] >= n) return(mm)
    if (n == 1) return(1)
    newr = addb(mulmat(fromb,tob,n-1) %*% rep(fromb-1,n-1), 1, tob)
    newm = mulmat(fromb,tob,n-1)
    while (is.null(dim(newm)) || dim(newm)[1] < length(newr)) newm = rbind(0,newm)
    mm <<-  cbind(newr, newm)
    return(mm)
}

dothelocomotion <- function(fromBase, toBase, v) {
    mm  <<- rbind(1)
    return(redb(mulmat(fromBase, toBase, length(v)) %*% v, toBase))
}

*> 500 तत्वों के लिए आपको डिफ़ॉल्ट पुनरावर्तन स्तर को उठाना होगा याmm मैट्रिक्स को रीसेट नहीं करना होगाdothelocomotion()

उदाहरण:

v1 = c(41, 15, 156, 123, 254, 156, 141, 2, 24)
dothelocomotion(256,16,v1)
2  9  0 15  9 12  7 11 15 14  9 12  8 13  0  2  1  8

dothelocomotion(256,36,c(41,42,43))
1 21 29 22  3

dothelocomotion(2,10, rep(1,90))
1 2 3 7 9 4 0 0 3 9 2 8 5 3 8 0 2 7 4 8 9 9 1 2 4 2 2 3

3

एक कम अस्पष्ट और तेज जावास्क्रिप्ट संस्करण:

function convert (number, src_base, dst_base)
{
    var res = [];
    var quotient;
    var remainder;

    while (number.length)
    {
        // divide successive powers of dst_base
        quotient = [];
        remainder = 0;
        var len = number.length;
        for (var i = 0 ; i != len ; i++)
        {
            var accumulator = number[i] + remainder * src_base;
            var digit = accumulator / dst_base | 0; // rounding faster than Math.floor
            remainder = accumulator % dst_base;
            if (quotient.length || digit) quotient.push(digit);
        }

        // the remainder of current division is the next rightmost digit
        res.unshift(remainder);

        // rinse and repeat with next power of dst_base
        number = quotient;
    }

    return res;
}

अभिकलन समय ओ के रूप में बढ़ता है (अंकों की संख्या 2 )।
बड़ी संख्या के लिए बहुत कुशल नहीं है।
विशिष्ट संस्करण लाइन बेस 64 एनकोडिंग गणनाओं को गति देने के लिए आधार अनुपात का लाभ उठाते हैं।


भगवान का काम कर रहे बेटे
bryc

2

जावास्क्रिप्ट

आपके पायथन जवाब के लिए कीथ रान्डेल धन्यवाद। मैं अपने समाधान के टकसाल के साथ संघर्ष कर रहा था और आपके तर्क की नकल कर रहा था। अगर कोई इस समाधान के लिए वोट दे रहा है क्योंकि यह काम करता है तो कृपया कीथ के समाधान के लिए भी वोट दें।

function convert(src,fb,tb){
  var res=[]
  while(src.length > 0){
    var a=(function(src){
      var d=[];var rem=0
      for each (var i in src){
        var c=i+rem*fb
        var e=Math.floor(c/tb)
        rem=c%tb
        d.length||e?d.push(e):0
      }
      return[d,rem]
    }).call(this,src)
    src=a[0]
    var rem=a[1]
    res.unshift(rem)
  }
  return res
}

टेस्ट

console.log(convert([1, 2, 3, 4], 16, 16))
console.log(convert([1, 0], 10, 100))
console.log(convert([41, 15, 156, 123, 254, 156, 141, 2, 24], 256, 16))
console.log(convert([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 2, 10))
console.log(convert([41, 42, 43], 256, 36))

/*
Produces:
[1, 2, 3, 4]
[10]
[2, 9, 0, 15, 9, 12, 7, 11, 15, 14, 9, 12, 8, 13, 0, 2, 1, 8]
[1, 2, 3, 7, 9, 4, 0, 0, 3, 9, 2, 8, 5, 3, 8, 0, 2, 7, 4, 8, 9, 9, 1, 2, 4, 2, 2, 3]
[1, 21, 29, 22, 3]
*/

यह शायद बहुत छोटा हो सकता है, लेकिन मैं वास्तव में इसे थोड़ा साइड प्रोजेक्ट के लिए उपयोग करना चाहता हूं। इसलिए मैंने इसे पठनीय (कुछ हद तक) रखा है और चर को जांच में रखने की कोशिश की है।


यह कैसे जावास्क्रिप्ट है? प्रत्येक के लिए?
हर्नान एचे

3 वर्णों के ऊपर कोई नाम परिवर्तन नहीं, पदावनत for eachकथन और आंखों का पानी जैसा निर्माण d.length||e?d.push(e):0... क्या यह एक अस्पष्ट कोड चुनौती है या कुछ और? आप एक समझदार वाक्य रचना और बेहतर प्रदर्शन के साथ एक ही बात लिख सकते हैं।

@kuroineko यह कोड गोल्फ है। आप क्या उम्मीद कर रहे थे अप-टू-डेट मानकों का उपयोग करते हुए स्वच्छ, पठनीय कोड? मैंने कभी दावा नहीं किया कि मेरा उत्तर सही था और मैं निश्चित रूप से इसका उपयोग नहीं करूंगा जैसा कि एक उत्पादन परियोजना में है।
स्टीफन पेरेल्सन

वैसे मुझे वास्तव में किसी कारण से जावास्क्रिप्ट में इस एल्गोरिथ्म की आवश्यकता थी, और मुझे इसे स्क्रैच से फिर से लिखना पड़ा, आधार के रूप में अजगर समाधान को लेना। मैं आपके योगदान की सराहना करता हूं, लेकिन व्यावहारिक उद्देश्यों के लिए यह शायद ही सभी IMHO में उपयोग करने योग्य था।

2

मेथेमेटिका

जब तक यह स्मृति में फिट नहीं होता तब तक कोई भी चर परिभाषित नहीं किया जाता है।

f[i_, sb_, db_] := IntegerDigits[FromDigits[i, sb], db];

टेस्ट ड्राइव:

f[{1,2,3,4},16,16]
f[{1,0},10,100]
f[{41,15,156,123,254,156,141,2,24},256,16]
f[{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
   1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
   1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},2,10]
f[{41,42,43},256,36]

बाहर

{1,2,3,4}
{10}
{2,9,0,15,9,12,7,11,15,14,9,12,8,13,0,2,1,8}
{1,2,3 7,9,4,0,0,3,9,2,8,5,3,8,0,2,7,4,8,9,9,1,2,4,2,2,3}
{1,21,29,22,3}

1

स्काला:

def toDecimal (li: List[Int], base: Int) : BigInt = li match {                       
  case Nil => BigInt (0)                                                             
  case x :: xs => BigInt (x % base) + (BigInt (base) * toDecimal (xs, base)) }  

def fromDecimal (dec: BigInt, base: Int) : List[Int] =
  if (dec==0L) Nil else (dec % base).toInt :: fromDecimal (dec/base, base)

def x2y (value: List[Int], from: Int, to: Int) =
  fromDecimal (toDecimal (value.reverse, from), to).reverse

परीक्षण के साथ टेस्टकोड:

def test (li: List[Int], from: Int, to: Int, s: String) = {
 val erg= "" + x2y (li, from, to)
 if (! erg.equals (s))
   println ("2dec: " + toDecimal (li, from) + "\n\terg: " + erg + "\n\texp: " + s)
}   

 test (List (1, 2, 3, 4), 16, 16, "List(1, 2, 3, 4)")
 test (List (1, 0), 10, 100, "List(10)")
 test (List (41, 15, 156, 123, 254, 156, 141, 2, 24), 256, 16, "List(2, 9, 0, 15, 9, 12, 7, 11, 15, 14, 9, 12, 8, 13, 0, 2, 1, 8)") 
 test (List (1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), 
   2, 10, "List(1, 2, 3, 7, 9, 4, 0, 0, 3, 9, 2, 8, 5, 3, 8, 0, 2, 7, 4, 8, 9, 9, 1, 2, 4, 2, 2, 3)") 
 test (List (41, 42, 43), 256, 36, "List(1, 21, 29, 22, 3)")

सभी टेस्ट पास किए।


1

जम्मू, 109 105

हजारों अंकों को संभालता है कोई पसीना। किसी पूर्णांक को नुकसान नहीं पहुंचा!

e=:<.@%,.|~
t=:]`}.@.(0={.)@((e{:)~h=:+//.@)^:_
s=:[t[:+/;.0]*|.@>@(4 :'x((];~[t((*/e/)~>@{.)h)^:(<:#y))1')

उदाहरण

256 16 s 41 15 156 123 254 156 141 2 24
2 9 0 15 9 12 7 11 15 14 9 12 8 13 0 2 1 8

256 36 s 41 42 43
1 21 29 22 3

16 16 s 1 2 3 4
1 2 3 4

256 46 s ?.1000$45
14 0 4 23 42 7 11 30 37 10 28 44 ...

time'256 46 s ?.3000$45'  NB. Timing conversion of 3000-vector.
1.96s

यह छोटा हो जाता है।


0

स्मालटाक, 128

o:=[:n :b|n>b ifTrue:[(o value:n//b value:b),{n\\b}]ifFalse:[{n}]].
f:=[:a :f :t|o value:(a inject:0into:[:s :d|s*f+d])value:t].

परीक्षण:

f value:#[41 15 156 123 254 156 141 2 24]
  value:256
  value:16. 
    -> #(2 9 0 15 9 12 7 11 15 14 9 12 8 13 0 2 1 8)

f value:#[1 2 3 4]
  value:16
  value:16.
    -> #(1 2 3 4)

f value:#[1 0]
  value:10
  value:100.
    -> #(10)

f value:#[1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1]
  value:2
  value:10.
    -> #(1 2 3 7 9 4 0 0 3 9 2 8 5 3 8 0 2 7 4 8 9 9 1 2 4 2 2 3)

f value:#[41 42 43]
  value:256
  value:36.
    -> #(1 21 29 22 3)

और आपके विशेष मनोरंजन के लिए ( चुनौती: यह पता लगाएं, इनपुट मूल्य के बारे में ऐसा क्या खास है ):

f value:#[3 193 88 29 73 27 40 245 35 194 58 189 243 91 104 156 144 128 0 0 0 0]
  value:256
  value:1000.
    -> #(1 405 6 117 752 879 898 543 142 606 244 511 569 936 384 0 0 0) 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.