Convert a number to another according to the rule

i has a sequence of numbers like:

1234 5678 778899 

I want to convert them to a form where they start with the smallest number possible

Example:

 5678 would be 1234 778899 would be 112233 2452 would be 1231 

I tried to do:

 index = 0 digit = 1 newCode = [] newCode.append(digit) while index != len(codice)-1: index += 1 if code[index] == code[index-1]: newCode.append(digit) else: digit += 1 newCode.append(digit) 

But it converts numbers like 5675 - 1234, so it does not work. Is there a better way to do this and what am I doing wrong?

+5
source share
6 answers

This can be done with dictionaries:

Edit: Therefore, I could misinterpret this question. From the above examples, I suggested that this means that the first digit is mapped to 1, the second to 2, etc.

 x = "5512" function = {} count = 1 output = "" for digit in x: if digit in function: output += function[digit] else: function[digit] = str(count) count += 1 output += function[digit] print(output) #Outputs 1123 (5->1, 1->2, 2->3) 
+7
source
 t = {} int(''.join(t.setdefault(d, str(len(t) + 1)) for d in str(n))) 

Demo:

 >>> for n in 5678, 778899, 2452: t = {} print(n, '->', int(''.join(t.setdefault(d, str(len(t) + 1)) for d in str(n)))) 5678 -> 1234 778899 -> 112233 2452 -> 1231 
+7
source

You only check if the digit is equal to the last digit, but this does not work, for example, 2452 . You must keep track of all previous numbers, using, for example, a dictionary , as in @wjmccann answer .

You can do this a little shorter, but by combining defaultdict with count . defaultdict remembers already seen digits, and count provides values ​​for new ones.

 import itertools, collections, functools def convert(n): d = collections.defaultdict(functools.partial(next, itertools.count(1))) return int(''.join(str(d[x]) for x in str(n))) print(convert(5678)) # 1234 print(convert(778899)) # 112233 print(convert(2452)) # 1231 

Or even shorter as suggested in the comments :

 def convert(n): d = collections.defaultdict(list("987654321").pop) return int(''.join(d[x] for x in str(n))) 

This uses defaultdict again, but uses pop from the list of numbers as a factory function, removing items from the end of the list when new numbers are needed.

+3
source

One line solution using .index() :

After you were misled about what you were trying to achieve, this is my second answer, which, I think, satisfies the requirements quite briefly.

 from collections import OrderedDict def transform(n): s = str(n) return int(''.join(str(list(OrderedDict.fromkeys(s)).index(e)+1) for e in s)) 

and some examples:

 >>> transform(5678) 1234 >>> transform(778899) 112233 >>> transform(2452) 1231 

code takes advantage of the fact that index will essentially give you the value for digit directly - without the need for a dictionary .

First we remove duplicates from string using OrderedDict.fromkeys() . Then from this we can check the index each digit to get its value . We need to add 1 to index , since the first should be 1 (not 0 ).

+2
source

TL DR

The following code works for your requirements using dictionary .

 out = [] for n in num: digits = {} last_digit = 1 new_num = '' #assign new values for s in str(n): #go through digits of number if digits.get(s, None) == None : #if new digit not assigned digits[s] = str(last_digit) #assign new_num += str(last_digit) last_digit += 1 else : new_num += digits[s] #get the val out.append(int(new_num)) print(out) 

#driver:

 IN : num = [1234, 5678, 778899, 2452] OUT : [1234, 1234, 112233, 1231] 
+1
source

if the code [index] == code [index-1]:

newCode.append (1)

  you using digit variable in both place.. 

else:

digit + = 1
newCode.append (number)

0
source

Source: https://habr.com/ru/post/1272979/


All Articles