Định danh duy nhất


31

Giới thiệu

Theo định nghĩa, định danh duy nhất nên là duy nhất. Có nhiều định danh giống nhau khiến một người lấy dữ liệu không mong muốn. Nhưng với dữ liệu đến đồng thời từ nhiều nguồn, có thể khó đảm bảo tính duy nhất. Viết một hàm duy nhất một danh sách các định danh.

Đây có thể là câu đố tồi tệ nhất tôi đã viết, nhưng bạn có ý tưởng.

Yêu cầu

Đưa ra một danh sách các số nguyên dương hoặc nhiều hơn, áp dụng các quy tắc sau cho mỗi số từ đầu đến cuối:

  • Nếu số này là số đầu tiên của loại này, hãy giữ nó.
  • Nếu trước đó đã gặp phải số này, hãy thay thế nó bằng số nguyên dương thấp nhất không tìm thấy ở bất kỳ đâu trong toàn bộ danh sách đầu vào hoặc bất kỳ đầu ra hiện có nào.

Đối với giải pháp:

  • Giải pháp có thể là một chương trình hoặc một chức năng.
  • Đầu vào có thể là một chuỗi, một mảng, được truyền dưới dạng đối số hoặc đầu vào bàn phím.
  • Đầu ra có thể là một chuỗi, một mảng hoặc được in ra màn hình.
  • Tất cả các số trong danh sách đầu ra là khác biệt.

Giả định

  • Danh sách đầu vào sạch sẽ. Nó chỉ chứa số nguyên dương.
  • Một số nguyên dương có phạm vi từ 1 đến 2 31 -1.
  • Ít hơn 256 MB bộ nhớ khả dụng cho các biến của chương trình của bạn. (Về cơ bản, không có mảng 2.147.483.648 phần tử nào được phép.)

Các trường hợp thử nghiệm

Input:  empty
Output: empty

Input:  5
Output: 5

Input:  1, 4, 2, 5, 3, 6
Output: 1, 4, 2, 5, 3, 6

Input:  3, 3, 3, 3, 3, 3
Output: 3, 1, 2, 4, 5, 6

Input:  6, 6, 4, 4, 2, 2
Output: 6, 1, 4, 3, 2, 5

Input:  2147483647, 2, 2147483647, 2
Output: 2147483647, 2, 1, 3

Chấm điểm

Chỉ là một mã golf đơn giản. Số byte thấp nhất vào thời điểm này tuần tới sẽ thắng.


4
Thêm trường hợp kiểm tra: 6, 6, 1, 2, 3, 4, 56, 7, 1, 2, 3, 4, 5
Adám

2
@ Adám không nên 6, 6, ...cho 6, 1, ...?
xnor

5
@ Adám Tôi nghĩ bạn đúng về điều đó, nhưng từ ngữ có thể rõ ràng hơn, "bộ" có đề cập đến các yếu tố gặp phải, tất cả các yếu tố của danh sách đầu vào hoặc các thành phần trong danh sách như hiện tại không?
xnor

3
@xnor 6, 6, 4, 4, 2, 2Trường hợp thử nghiệm xác nhận cách giải thích của Adám: đầu ra dự kiến ​​là 6, 1, 4, 3, 2, 5, và không 6, 1, 4, 2, 3, 5.
Gây tử vong vào

2
Có 0 được tính là một số nguyên dương cho thử thách này không?
Lu-ca

Câu trả lời:



8

Java 8, 158 144 byte

a->{int m=0;String r="",c=",",b=r;for(int x:a)b+=x+c;for(int x:a)if(r.contains(x+c)){for(;(r+b).contains(++m+c););r+=m+c;}else r+=x+c;return r;}
  • .contains(m+c);m++)để .contains(++m+c);)lưu 1 byte và đồng thời chuyển đổi sang Java 8 để lưu thêm 13 byte.

Giải thích:

Hãy thử nó ở đây.

a->{                      // Method with integer-array parameter and String return-type
  int m=0;                //  Lowest integer
  String r="",            //  Result-String
         c=",",           //  Comma delimiter for result String
         b=r;for(int x:a)b+=x+c;
                          //  Input array as String
  for(int x:a)            //  Loop (2) over the integers in the array
    if(r.contains(x+c)){  //   If the result already contains this integer
      for(;(r+b).contains(++m+c););
                          //    Inner (3) as long as either the result-String or array-String contains the lowest integer
                          //     and raise the lowest integer before every iteration by 1
      r+=m+c;             //    Append the result with this lowest not-present integer
    }else                 //   Else:
      r+=x+c;             //    Append the result-String with the current integer
                          //  End of loop (2) (implicit / single-line body)
  return r;               //  Return the result-String
}                         // End of method

7

JavaScript (ES6), 49 byte

a=>a.map(g=(e,i)=>a.indexOf(e)-i?g(++n,-1):e,n=0)

7

Ruby , 63 byte

->a{r=*0..a.size;r.map{|i|[a[i]]-a[0,i]==[]?a[i]=(r-a)[1]:0};a}

Hãy thử trực tuyến!

Giải trình

->a{                                    # Anonymous function with one argument
    r=*0..a.size;                       # Numbers from 0 to array size
    r.map{|i|                           # For all numbers in range:
        [a[i]]                          #  Get array with just a[i]
              -a[0,i]                   #  Remove elements from array that are
                                        #    also in a[0..i-1]
                    ==[]?               #  Check if result is an empty array
                        a[i]=           #  If true, set a[i] to:
                             (r-a)      #   Remove elements from number range
                                        #     that are also in input array
                                  [1]   #   Get second element (first non-zero)
                        :0};            #  If false, no-op
                            a}          # Return modified array

6

05AB1E , 17 16 18 byte

vy¯yåi¹gL¯K¹K¬}ˆ}¯

Hãy thử trực tuyến!

Giải trình

v                    # for each y in input
 y                   # push y
  ¯yåi               # if y exist in global list
      ¹gL            # push [1 ... len(input)]
         ¯K          # remove any number that is already in global list
           ¹K        # remove any number that is in the input
             ¬       # get the first (smallest)
              }      # end if
               ˆ     # add to global list
                }¯   # end loop, push and output global list

Tôi có lẽ nên sử dụng giảm thay vì bản đồ ... hãy để tôi xem nếu điều đó có ích
Leaky Nun

@LeakyNun: Giảm hoặc bản đồ thường là cách để đi :)
Emigna


3
Cho [6, '1', '2', '3', '4', '5', '7']. Nên cho [6, '7', '1', '2', '3', '4', '5'].
Adám

1
@ Adám: Cảm ơn đã bắt! Đã sửa ngay :)
Emigna

6

PHP, 121 byte

<?$n=array_diff(range(0,count($g=$_GET)),$g);sort($n);$r=[];foreach($g as$v)$r[]=in_array($v,$r)?$n[++$i]:$v;print_r($r);

Phiên bản trực tuyến

Mở rộng

$n=array_diff(range(0,count($g=$_GET)),$g); # create array of ascending values which are not in input array plus zero
sort($n); # minimize keys
$r=[];  # empty result array
foreach($g as$v) # loop input array
  $r[]=in_array($v,$r)?$n[++$i]:$v; # if value is not in result array add value else take new unique value skip zero through ++$i
print_r($r); # output result array

5

Python 2, 77 79 byte

a=input();u=[];j=1
for x in a:
 u+=[[x,j][x in u]]
 while j in u+a:j+=1
print u

Đưa đầu vào bàn phím, thích [3, 3, 3, 3, 3, 3].

Chỉ cần theo dõi các số nguyên dương nhỏ nhất jkhông được sử dụng cho đến nay. Đối với mỗi thành phần xcủa đầu vào, đầu ra xnếu xchưa được sử dụng, nếu không thì đầu ra j. Cuối cùng, cập nhật jmỗi khi bạn xuất một cái gì đó.

EDITED: để sửa lỗi xử lý lỗi đầu vào của [6, 6, 4, 4, 2, 2]. Cảm ơn @Rod đã chỉ ra lỗi cũng như cách khắc phục. Sai lầm là, trong trường hợp có mục trùng lặp, nó sẽ xuất ra số nhỏ nhất không được sử dụng cho điểm đó trong danh sách, ngay cả khi đầu ra đó xuất hiện sau trong đầu vào. (Điều này là sai, như đã làm rõ trong bài đăng và các bình luận, nhưng tôi vẫn nhầm lẫn bằng cách nào đó.) Dù sao, cách khắc phục chỉ đơn giản là thêm danh sách đầu vào a, vào tập hợp các giá trị không thể xuất ra trong trường hợp đó.


không hoạt động [6,6,4,4,2,2], bạn có thể (có thể) sửa nó bằng cách thêm +avào while j in u:->while j in u+a:
Rod

@Rod Bạn nói đúng, lỗi của tôi. . sửa chữa, và xác minh nó chống lại các trường hợp thử nghiệm. Cảm ơn!
mathmandan

5

Haskell , 79 76 byte

CHỈNH SỬA:

  • -3 byte: @nimi thấy headcó thể được thay thế bằng khớp mẫu.

([]#)là một chức năng ẩn danh lấy và trả về một danh sách. Sử dụng như([]#)[2147483647, 2, 2147483647, 2] .

(?)=notElem
s#(x:y)|z:_<-[x|x?s]++filter(?(s++y))[1..]=z:(z:s)#y
_#n=n
([]#)

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

  • ? là một toán tử viết tắt để kiểm tra nếu một phần tử vắng mặt trong danh sách.
  • s#lxử lý danh sách các số nguyên l, đưa ra một danh sáchs các số nguyên đã được sử dụng.
    • x là số nguyên tiếp theo để xem xét, y những số còn lại.
    • zlà số nguyên được chọn cho vị trí tiếp theo. Đó là xnếu xkhông phải là một phần tử của s, và số nguyên dương đầu tiên không có trong shay ykhác.
    • (z:s)#ysau đó đệ quy với zthêm vào danh sách số nguyên được sử dụng.
    • n là một danh sách trống, vì các danh sách không trống đã được xử lý trong dòng trước.
  • Hàm chính ([]#)lấy một danh sách và gọi #nó là đối số thứ hai và một danh sách trống cho đối số thứ nhất.

|z:_<-[x|...]...
nimi

4

APL (Dyalog 16.0), 34 byte

(s↑v~⍨⍳⌈/v+s←+/b←(⍳≢v)≠⍳⍨v)@{b}v←⎕

2
Phải có cách tốt hơn.
Adám


3

C # , 135 byte


Chơi gôn

(int[] i)=>{for(int x=1,v,m=0,l=i.Length,y;x<l;x++){v=i[x];for(y=0;y<l&&v==i[x]?y<x:y<l;y++)if(i[y]==v){v=++m;y=-1;}i[x]=v;}return i;};

Ung dung

( int[] i ) => {
   for( int x = 1, v, m = 0, l = i.Length, y; x < l; x++ ) {
      v = i[ x ];

      for( y = 0; y < l && v == i[ x ] ? y < x : y < l ; y++ )
         if( i[ y ] == v ) {
            v = ++m;
            y = -1;
         }

      i[ x ] = v;
   }

   return i;
};

Ungolfed có thể đọc được

// Takes an array of Int32 objects ( 32-byte signed integers )
( int[] i ) => {

   // Cycles through each element on the array
   //   x: Scan position, starts at the 2nd element
   //   v: Value being processed
   //   m: The next minimum value to replace
   //   l: Size of the array, to save some byte count
   for( int x = 1, v, m = 0, l = i.Length, y; x < l; x++ ) {

      // Hold the value
      v = i[ x ];

      // Re-scan the array for a duplicate value up the the current position ( 'x' ) IF
      //   ... the currently hold value hasn't been modified
      //   ... otherwise, re-scans the entire array to find a suitable value to replace
      for( y = 0; y < l && v == i[ x ] ? y < x : y < l ; y++ )

         // Check if 'v' shares the same value with other element
         if( i[ y ] == v ) {

            // Set 'v' to the minimum value possible
            v = ++m;

            // Reset the scan position to validate the new value
            y = -1;
         }

      // Set the 'v' to the array
      i[ x ] = v;
   }

   // Return the array
   return i;
};

Mã đầy đủ

using System;
using System.Collections.Generic;

namespace Namespace {
   class Program {
      static void Main( String[] args ) {
         Func<Int32[], Int32[]> f = ( int[] i ) => {
            for( int x = 1, v, m = 0, l = i.Length, y; x < l; x++ ) {
               v = i[ x ];

               for( y = 0; y < l && v == i[ x ] ? y < x : y < l ; y++ )
                  if( i[ y ] == v ) {
                     v = ++m;
                     y = -1;
                  }

               i[ x ] = v;
            }

            return i;
         };

         List<Int32[]>
            testCases = new List<Int32[]>() {
               new Int32[] { },
               new Int32[] { 5 },
               new Int32[] { 1, 4, 2, 5, 3, 6 },
               new Int32[] { 3, 3, 3, 3, 3, 3 },
               new Int32[] { 6, 6, 4, 4, 2, 2 },
               new Int32[] { 2147483647, 2, 2147483647, 2 },
            };

         foreach( Int32[] testCase in testCases ) {
            Console.WriteLine( $" Input: {String.Join( ",", testCase )}\nOutput: {string.Join( ",", f( testCase ) )}\n" );
         }

         Console.ReadLine();
      }
   }
}

Phát hành

  • v1.0 - 135 bytes- Giải pháp ban đầu.

Ghi chú

  • không ai


3

R , 39 46 byte

Tạo một vectơ từ đầu vào, sau đó thay thế các giá trị trùng lặp với phạm vi từ 1 đến một triệu đã loại bỏ các giá trị đầu vào. Trả về một vectơ số. Không có đầu vào sẽ trả về số vector trống (0).

i[duplicated(i)]=(1:1e6)[-(i=scan())];i

Hãy thử trực tuyến!

Điều này sẽ đưa ra một cảnh báo về chiều dài của vectơ thay thế

                           i=scan()     # set i as input
                 (1:1e6)                # 1 to a million (could go higher)
                 (1:1e6)[-(i=scan())]   # without input values
  duplicated(i)                         # duplicate values in i
i[duplicated(i)]=(1:1e6)[-(i=scan())]   # set duplicate i values to reduced range vector
                                     ;i # return result

3

C, 169 byte 133 byte

đầu vào = mảng a, đầu ra = mảng sửa đổi a

i=1,j,k,l;void f(int*a,int n){for(;i<n;i++)for(j=i-1;j>=0;j--)if(a[i]==a[j]){l=1;for(k=0;k<n;)if(l==a[k])k=l++?0:0;else k++;a[i]=l;}}

được định dạng

int i, j, k, l;
void f(int* a, int n)
{
    for (i = 1; i<n; i++)
        for (j = i - 1; j >= 0; j--)
            if (a[i] == a[j])
            {
                l = 1;
                for (k = 0; k<n;)
                    if (l == a[k])
                        k = l++ ? 0 : 0;
                    else
                        k++;
                a[i] = l;
            }
}

Quá nhiều byte lãng phí cho các vòng lặp này. Có ai nghĩ đến việc rút ngắn mã bằng cách phát minh ra một thuật toán mới (sử dụng ít vòng lặp hơn) không? Tôi đã suy nghĩ nhưng chưa tìm thấy một.


2

C # 7, 116 byte

int[]f(int[]c){int j=0;int h()=>c.Contains(++j)?h():j;return c.Select((e,i)=>Array.IndexOf(c,e)<i?h():e).ToArray();}

Thụt lề

int[] f(int[] c)
{
    int j = 0;
    int h() => c.Contains(++j) ? h() : j;
    return c
        .Select((e, i) => Array.IndexOf(c, e) < i ? h() : e)
        .ToArray();
}

Giải thích

  • lần đầu tiên xuất hiện của một số luôn luôn như cũ
  • sự xuất hiện liên tiếp của một số được rút ra từ [1, 2, 3, ...], bỏ qua các giá trị có trong đầu vào.

Phiên bản trực tuyến


2

Clojure, 72 byte

#(reduce(fn[r i](conj r(if((set r)i)(nth(remove(set r)(range))1)i)))[]%)

Một giảm cơ bản. Nếu iđược chứa trong danh sách đầu ra cho đến nay, chúng ta sẽ lấy phần tử thứ 2 (1 khi được lập chỉ mục 0) từ danh sách số nguyên vô hạn (range)mà chúng ta đã loại bỏ những số đã được sử dụng. Phạm vi bắt đầu từ 0 nên chúng ta không thể lấy phần tử đầu tiên mà là phần tử thứ hai.


1

R, 74 byte

đọc danh sách từ stdin; trả về NULL cho một đầu vào trống.

o=c();for(i in n<-scan())o=c(o,`if`(i%in%o,setdiff(1:length(n),o)[1],i));o

giải trình:

o=c()                                #initialize empty list of outputs
for(i in n<-scan())                  # loop through the list after reading it from stdin
    o=c(o,                           # set the output to be the concatenation of o and
      `if`(i%in%o,                   # if we've seen the element before
           setdiff(1:length(n),o)[1] # the first element not in 1,2,...
           ,i))                      # otherwise the element
o                                    # print the output

1:length(n) có thể được sử dụng vì chúng tôi được đảm bảo không bao giờ cần thay thế từ bên ngoài phạm vi đó.

Hãy thử trực tuyến!


0

Tiên đề, 169 byte

f a==(r:List INT:=[];for i in 1..#a repeat(~member?(a.i,r)=>(r:=concat(r,a.i));for j in 1..repeat if~member?(j,r)and(~member?(j,a)or j=a.i)then(r:=concat(r,j);break));r)

ungolf và kết quả

ff(a)==
  r:List INT:=[]
  for i in 1..#a repeat
      ~member?(a.i,r)=>(r:=concat(r,a.i))
      for j in 1.. repeat
            if~member?(j,r)and(~member?(j,a) or j=a.i)then(r:=concat(r,j);break)
  r

(3) -> f([])
   (3)  []
                                                       Type: List Integer
(4) -> f([5])
   (4)  [5]
                                                       Type: List Integer
(5) -> f([1,4,2,5,3,6])
   (5)  [1,4,2,5,3,6]
                                                       Type: List Integer
(6) -> f([3,3,3,3,3,3])
   (6)  [3,1,2,4,5,6]
                                                       Type: List Integer
(7) -> f([6, 6, 4, 4, 2, 2])
   (7)  [6,1,4,3,2,5]
                                                       Type: List Integer
(8) -> f([2147483647, 2, 2147483647, 2])
   (8)  [2147483647,2,1,3]
                                                       Type: List Integer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.