Chris Maunder Ответов: 8

Задача кодирования: расположите числа так, чтобы они образовывали как можно большее целое число


Проблема позднего кодирования на сегодняшний день проста.

Учитывая набор целых чисел, расположите их так, чтобы полученное таким образом конечное целое число было максимально возможным.

Например.

{ 1,5,67,9 } будет организовано так, чтобы сформировать 96751

Список может содержать до 50 чисел,и каждое число будет меньше 256 и положительным.

Что я уже пробовал:

Чтобы проблемы оставались достаточно двусмысленными.

На прошлой неделе победителем стал Graeme_Grant, главным образом потому, что он научил нас всем словам, которых мы никогда не знали. Пошлите Шону свои данные, и что-нибудь (возможно) подходящее отправит его домой.

PIEBALDconsult

- Чтобы проблемы оставались достаточно двусмысленными."


1 == 1
5 == 101
9 == 1001
67 == 1000011

110110011000011

Graeme_Grant

Linq делает это просто...

var sorted = (new [] { 1, 5, 67, 9 }).Выберите (i => i. ToString ()).OrderByDescending (i => i).Выберите (i = & gt; Convert.ToInt32 (i)).Метод toArray();

но где в этом веселье?.. ;)

Graeme_Grant

Это немного сложнее, чем это, поэтому я создал однострочное решение Linq[^] ниже.

Patrice T

Идея: сохранение пробелов в ответе помогает читать порядок чисел.

Graeme_Grant

Мой вывод был сделан в соответствии с запросом Криса. Нетрудно добавить пробелы, если это необходимо. ;)

Patrice T

это была всего лишь идея, а не жалоба.
"Нетрудно добавить пробелы"
Да, но легче с пространствами, которые уже есть.

Graeme_Grant

Я работаю с необработанными данными и спецификациями весь день ... просто привычка к конформизму. Да, вы правы, пространства делает сделайте его более легким для чтения-так данные маркируют наборы данных. :)

Patrice T

Я думаю, что мы можем взять на себя некоторую свободу в этом заявлении.
помните, что решения, дающие неправильный круг, были приняты.
Кстати, вы выяснили, почему ваш перевод не сработал?

Graeme_Grant

Извини, забыл об этом. Сегодня вечером я еще раз взгляну на него.

Graeme_Grant

Я только что опубликовал решение 5-визуализируйте 3 различных алгоритма сортировки в действии. Алгоритмы сортировки кодируются вручную, а не позволяют Linq выполнять всю тяжелую работу. Я оставил его с пробелами, а не с соединенной строкой. ;)

PIEBALDconsult

Просто сказал моему принять "6.7 E+1" как целое число...: D

8 Ответов

Рейтинг:
2

H2O-au

В LINQ один-лайнер! (Ну, если честно, примерно восемь строк жестоко сплелись в одну...)

public static BigInteger DoChallenge(this IEnumerable<byte> question)
{
    return (from x in question
            orderby (x < 10) ? x * 1110 :
                    (x < 100) ? x * 100 + Math.Min(x, (x % 10) * 10 + x / 10) :
                    x * 10 descending
            select new BigInteger(x))
        .Aggregate((x, y) =>
            (y < 10) ? x * 10 + y :
            (y < 100) ? x * 100 + y :
            x * 1000 + y);
}
Математическая идея состоит в том, чтобы преобразовать каждое 1-2-и 3-значное число в 4-значное число для целей сортировки:
  • 123 идет до 1230
  • 12 переходит к 1212, прорезая его между 122 (1220) и 121 (1210)
  • 21 переходит к 2112, прорезая его между 212 (2120) и 211 (2110)
  • 2 идет к 2220, прорезая его между 223 (2230) и 221 (2210), а также между 23 (2323) и 21 (2112)
Похоже, он работает для множества разнообразных тестовых случаев, хотя еще не полностью протестирован и не доказан.


Graeme_Grant

Я получаю неправильный результат для этого набора: { 1, 5, 67, 94, 96, 91, 9 } - 910668943 вместо 99694916751

H2O-au

Да, я получаю 910668943, когда использую int вместо системы.Численные данные.Типа BigInteger. Агрегация эпопеи-терпит неудачу. Похоже, что скромные Инты не могут справиться со 150-значными числами! :D Хотя с BigInteger я получаю 99694916751.

Graeme_Grant

ах... инт против Бигинта ... попался! Проверю это позже... :)

Patrice T

Я получаю: 9 96 94 91 67 5 1

Graeme_Grant

"Задан набор целых чисел..." - входные данные должны быть типа int, а не byte...

PIEBALDconsult

Струны проще...

Graeme_Grant

Я стараюсь кодировать вызов так, как будто это спецификация. Крис попросил Int [] / List< int> Для ввода и одно число в качестве строки для вывода. То, что мы делаем в середине, зависит только от нас. ;)

PIEBALDconsult

- Чтобы проблемы оставались достаточно двусмысленными."

Я бы не был таким ограничительным; он не просил Int [] / List< int>.

Graeme_Grant

С нетерпением жду того, что вы придумаете... :)

PIEBALDconsult

Вы видели мой комментарий по поводу вызова?

Graeme_Grant

Вы видели, что я тоже написал чуть ниже вашего? ;)

Chris Maunder

Я сказал "набор целых чисел", а не"набор значений типа int". Я имею в виду целые числа в математическом смысле.

Graeme_Grant

Плохая привычка работать с RFC, техническими документами и т. д. весь день... Рад узнать, что ваши определения расплывчаты... :)

PIEBALDconsult

О черт, набор не допускает дубликатов, мое решение (пока) допускает дубликаты, но я могу легко изменить это или сделать его настраиваемым...

Chris Maunder

С каких это пор набор не допускает дубликатов? Набор шариков может содержать два шарика, которые являются одинаковыми.

PIEBALDconsult

Множество в математическом смысле.

И нет двух одинаковых шариков.

H2O-au

На самом деле, моя главная причина использования байта более коварна. Я знаю, что мой алгоритм терпит неудачу для чисел выше 999. Я не мог потрудиться пройти и проверить, что все номера меньше 999, поэтому, используя байт, я покрываю необходимый диапазон, но делаю целостность данных ответственностью вызывающего абонента! ;Д

Я уверен, что мог бы оправдать это, пробормотав что-то о "безопасности типов", но, вероятно, я просто ленив...

Рейтинг:
1

PIEBALDconsult

System.Console.WriteLine ( BiggestIntegerInator
(
  System.Environment.CommandLine.Rive 
  ( Option.RemoveEmptyEntries 
  | Option.RemoveQuotes 
  | Option.HonorEscapes 
  | Option.HonorQuotes 
  )
) ) ;


(Рив есть в одной из моих статей, это более гибкая версия Split.)

1 05 6.7E+1 "9" доходность 96751


private static string
BiggestIntegerInator
(
  System.Collections.Generic.IList<string> Values
)
{
  System.Text.StringBuilder result = new System.Text.StringBuilder() ;

  System.Collections.Generic.SortedList<string,int> l =
    new System.Collections.Generic.SortedList<string,int>
    (
      Values.Count
    ,
      new DescendingComparer<string>()
    ) ;

  for ( int i = 0 ; i < Values.Count ; i++ )
  {
    string v = Values [ i ] ;

    double j ;

    if ( System.Double.TryParse ( v , out j ) && ( ( v = j.ToString() ).IndexOf ( '.' ) == -1 ) )
    {
      if ( l.ContainsKey ( v ) )
      {
        l [ v ]++ ;
      }
      else
      {
        l [ v ] = 1 ;
      }
    }
  }

  for ( int i = 0 ; i < l.Count ; i++ )
  {
    string v = l.Keys [ i ] ;

    for ( int j = 0 ; j < l [ v ] ; j++ )
    {
      result.Append ( v ) ;
    }
  }

  return  ( result.ToString() );
}

private class DescendingComparer<T> : System.Collections.Generic.IComparer<T>
where T : System.IComparable<T>
{
  public int
  Compare
  (
    T Op0
  ,
    T Op1
  )
  {
    return ( Op1.CompareTo ( Op0 ) ) ;
  }
}


Хорошо, так что этот компаратор выше не совсем подходит, вот еще один:

private class DescendingNumericStringComparer : System.Collections.Generic.IComparer<string>
{
  public int
  Compare
  (
    string Op0
  ,
    string Op1
  )
  {
    int result = 0 ;

    int i0 = -1 ;
    int i1 = -1 ;

    while ( ( result == 0 ) && ( ( i0 < Op0.Length - 1 ) || ( i1 < Op1.Length - 1 ) ) )
    {
      if ( i0 < Op0.Length - 1 ) i0++ ;
      if ( i1 < Op1.Length - 1 ) i1++ ;

      result = Op1 [ i1 ].CompareTo ( Op0 [ i0 ] ) ;
    }

    if ( result == 0 )
    {
      result = Op0.Length.CompareTo ( Op1.Length ) ;
    }

    return ( result ) ;
  }
}


43 432 435 433 доходность 435 43 433 432


Так что у этого тоже есть недостаток. Вот небольшое грязное исправление (не рекомендуется из-за манипуляций со строками), пока я работаю над лучшей реализацией:

private class DescendingStringComparer : System.Collections.Generic.IComparer<string>
{
  public int
  Compare
  (
    string Op0
  ,
    string Op1
  )
  {
    int result = (Op1 + Op0).CompareTo ( Op0 + Op1 ) ;

    if ( result == 0 )
    {
      result = Op0.Length.CompareTo ( Op1.Length ) ;
    }

    return ( result ) ;
  }
}


24 242 243 доходность 243 24 242

Четвертый компаратор, без конкатенации строк.
Возьмите более длинную из двух длин и повторите.
Когда у нас закончатся символы в одном из значений, начните использовать символы в начале другого значения.

private class DescendingStringComparer : System.Collections.Generic.IComparer<string>
{
  public unsafe int
  Compare 
  (
    string Op0
  ,
    string Op1
  )
  {
    int result = 0 ;

    int len = Op0.Length > Op1.Length ? Op0.Length : Op1.Length ;

    for ( int i = 0 ; ( result == 0 ) && ( i < len ) ; i++ )
    {
      char c0 = i < Op0.Length ? Op0 [ i ] : Op1 [ i - Op0.Length ] ;
      char c1 = i < Op1.Length ? Op1 [ i ] : Op0 [ i - Op1.Length ] ;
              
      result = c1.CompareTo ( c0 ) ;
    }

    if ( result == 0 )
    {
      result = Op0.Length.CompareTo ( Op1.Length ) ;
    }

    return ( result ) ;
  }
}


Patrice T

Ху,
Я не понимаю, как вы заполняете маленькие числа.
Как вы справляетесь с 4 45 46 43 и 43 432 435 433 ?

PIEBALDconsult

Я не знаю, с чего бы?
Хммм... Мне кажется, я вижу проблему...

Graeme_Grant

Мне нравится идея SortedList использование пользовательского компаратора - я об этом не подумал! :)

Но ppolymorphe прав, попробуйте этот набор: {1, 5, 67, 94, 96, 91, 9}. Ваш выход: 96-94-91-9-67-5-1 но должен дать: 9-96-94-91-67-5-1-последнее больше числа-996...51 больше числа, чем 969...51

Graeme_Grant

Я подключил его и он исправил выход:

private class InvertedCodeProjectComparer<T> : IComparer<T> where T : IComparable<T>
{
    int IComparer<T>.Compare(T x, T y)
        => Convert.ToInt32(string.Join("", new[] { y, x })) -
           Convert.ToInt32(string.Join("", new[] { x, y }));
}

PIEBALDconsult

Я нахожусь на нем, просто проверяю сейчас...

Graeme_Grant

Извините, но у вас есть еще одна проблема (используя ваш компаратор-любой на самом деле):

Вход: {122, 151, 169, 139, 99, 245, 31, 67, 42, 61, 180, 52, 248, 200, 90, 223, 109, 51, 91, 98, 186, 191, 215, 70, 193, 179, 43, 84, 203, 228, 106, 246, 142, 150, 81, 145, 123, 229, 135, 120, 41, 40, 9, 234, 53, 156, 115, 24, 220, 233} || элементы: 50

Выход: 99 98 91 90 9 84 81 70 67 61 53 52 51 43 42 41 40 31 248 246 245 24 234 233 229 228 223 220 215 203 200 193 191 186 180 179 169 156 151 150 145 142 139 135 123 122 120 115 109 106 || элементы: 51

Расставлены так, чтобы легче было заметить Уолли ;)

PIEBALDconsult

Новый компаратор производит:
9 99 98 91 90 84 81 70 67 61 53 52 51 43 42 41 40 31 248 246 245 24 234 233 229 228 223 220 215 203 200 193 191 186 180 179 169 156 151 150 145 142 139 135 123 122 120 115 109 106

Graeme_Grant

Рад видеть, что это работает. :)

PIEBALDconsult

А как вы вычисляете 51 элемент?

Graeme_Grant

в одном случайном тесте было дополнительно 9 ...

{122, 151, 169, 139, 99, 245, 31, 67, 42, 61, 180, 52, 248, 200, 90, 223, 109, 51, 91, 98, 186, 191, 215, 70, 193, 179, 43, 84, 203, 228, 106, 246, 142, 150, 81, 145, 123, 229, 135, 120, 41, 40, 9, 234, 53, 156, 115, 24, 220, 233}

в результате: 99999891908481706761535251434241403124824624524234233229228223220215203200193191186180179169156151150145142139135123122120115109106

При просмотре я вижу, что в приведенном выше примере, когда я изменил исходный код на count, я не сказал split Игнорировать пустые результаты - извините.

Но с этим тестом происходит что-то странное...

PIEBALDconsult

А, ладно.

Рейтинг:
1

Patrice T

Снова мой язык Clipper (семейство xBase, как и FoxPro).
Процедура:
1) преобразование в строки
2) отсортируйте числа в обратном порядке после некоторого заполнения до того же размера.

*   CCCP Code Challenge Code Project
*    Build largest integer
clear
largest({1, 5, 67, 9})
largest({100, 11, 10, 110, 112,1,114})
largest({4, 45, 46, 43})
largest({43, 432, 435, 433})
largest({2, 243, 242, 245, 241, 24, 221})
largest({20, 221, 226, 202, 2, 201})

procedure largest(lst)
	*	convert 2 string
	for scan=1 to len(lst)
		lst[scan]= str(lst[scan],,,.T.)
	next
	?
	? lst[1]
	for scan=2 to len(lst)
		?? " "
		?? lst[scan]
	next
		
	*	tri par insertion
	for scan=2 to len(lst)
		for ptr= scan to 2 step -1
			*	pad until same lentgh 
			mx= max(len(lst[ptr]), len(lst[ptr-1]))+1
			tmp1= lst[ptr]
			while len(tmp1) < mx
				tmp1 += lst[ptr]
			enddo
			tmp1= left(tmp1,mx)
			
			tmp2= lst[ptr-1]
			while len(tmp2) < mx
				tmp2 += lst[ptr-1]
			enddo
			tmp2= left(tmp2,mx)
			
			if tmp1 > tmp2
				tmp= lst[ptr]
				lst[ptr]= lst[ptr-1]
				lst[ptr-1]= tmp
			endif
		next
	next
	
	*	result
	? lst[1]
	for scan=2 to len(lst)
		?? " "
		?? lst[scan]
	next
	
	return

Вариант без заполнения строк:
for scan=2 to len(lst)
    for ptr= scan to 2 step -1
        if len(lst[ptr])= len(lst[ptr-1])
            tmp1= lst[ptr]
            tmp2= lst[ptr-1]
        else
            mx= len(lst[ptr])+ len(lst[ptr-1])- 1
            for scanl= 0 to mx
                tmp1= lst[ptr, scanl%len(lst[ptr])+1]
                tmp2= lst[ptr-1, scanl%len(lst[ptr-1])+1]
                if tmp1 != tmp2
                    exit
                endif
            next
        endif
        if tmp1 > tmp2
            tmp= lst[ptr]
            lst[ptr]= lst[ptr-1]
            lst[ptr-1]= tmp
        endif
    next
next

Тестовый набор
1 5 67 9
9 67 5 1

100 11 10 110 112 1 114
114 112 11 1 110 10 100

4 45 46 43
46 45 4 43

43 432 435 433
435 43 433 432

2 243 242 245 241 24 221
245 243 24 242 241 2 221

20 221 226 202 2 201
226 2 221 202 20 201

Примечание: пробелы в ответах просто помогают понять, как упорядочены числа.

[Обновление] уточнил часть сортировки
Заполнение части действительно сложно, мое лучшее предположение до сих пор:
Обивка должна быть сделана до максимальной длины + 1
Заполнение должно быть сделано путем повторения значения.

Возьмите 20 и 202. Что это за приказ ?
обивка: 20 - & gt; 2020, 202 -> 2022
Порядок такой же, как на 2020 и 2022 годы, так что 202, 20.

Возьмите 24 и 242. Что это за приказ ?
обивка: 24 - > 2424, 242 -> 2422
Порядок такой же, как для 2424 и 2422, так что 24, 242.


Рейтинг:
1

Graeme_Grant

Вот еще один Linq one-liner. Я завернул его как метод расширения. Компаратор можно использовать как для восходящего, так и для нисходящего расчета, хотя для этой задачи требуется только нисходящее положительное число в диапазоне от 1 до 256.

Основная логика-это простой однострочный алгоритм, который можно использовать с любым алгоритмом сортировки-поочередно соединять (а не складывать) числа и вычитать первое значение из второго. Отрицательный результат означает, что левый меньше (нам нужно поменять местами), ноль равен (ничего не делать), а положительный-что левый больше (ничего не делать). например: {94, 9} = 949 - 994 = -45, поэтому нам нужно поменять местами числа, и новая последовательность должна быть {9, 94}. Однако, {1, 112} = 1112 - 1121 = -9, таким образом, правильный порядок - {112, 1}.

Вот метод сравнения, который делает всю работу:

class CodeProjectComparer : IComparer<int>
    {
        int IComparer<int>.Compare(int x, int y)
            => Convert.ToInt32(string.Join("", new[] { x, y })) -
               Convert.ToInt32(string.Join("", new[] { y, x }));
    }

Этот class может использоваться с любым алгоритмом сортировки. Я добавил Решение 5 это наглядно демонстрирует эффективность приведенного выше метода сравнения с использованием до 9 различных алгоритмов сортировки.

Если вы хотите не отдельный класс, а скорее как выражение-тело члена[^]:
Comparer<int> Compare()
        => Comparer<int>.Create((x, y)
            => Convert.ToInt32(string.Join("", new[] { x, y })) -
               Convert.ToInt32(string.Join("", new[] { y, x })));

Вот однострочный Linq (используемый в этом решении), который включает в себя встроенный компаратор:
public static string ArrangedFormNumbersDescending(this int[] nums)
    => string.Join("", 
                   nums.OrderByDescending(
                       i => i, 
                       Comparer<int>.Create((x, y)
                           => Convert.ToInt32(string.Join("", new[] { x, y })) - 
                              Convert.ToInt32(string.Join("", new[] { y, x })))));

Примечание: Если вам интересно посмотреть, как Microsoft реализует сортировку для своего Linq OrderBy и OrderByDescending, вы можете просмотреть их исходный код[^].

Ниже приведен пример приложения, использующего однострочный Linq и вывод, который он генерирует.

Вот моя попытка полностью рабочей версии сделать решение "достаточно неоднозначным", чтобы удовлетворить одно из требований задачи:
using System                                                                                      ;
using System.Collections.Generic                                                                  ;
using System.Linq                                                                                 ;

namespace ArrangedFormNumbers                                                                     {
    static class Program                                                                          {
        static void Main(string[] args)                                                           {
            var max = 50                                                                          ;
            var r = new Random()                                                                  ;
            var randomSet = new int[max]                                                          ;

            for (int i = 0; i < max; i++)                                                         {
                for (;;)                                                                          {
                    var n = r.Next(1, 255)                                                        ;
                    if (!randomSet.Contains(n))                                                   {
                        randomSet[i] = n                                                          ;
                        break                                                                     ;
                                                                                                  }
                                                                                                  }
                                                                                                  }
            var tests = new List<int[]>()                                                         {
                new[] { 1, 5, 67, 9 },
                new[] { 1, 5, 67, 94, 96, 91, 9 },
                new[] { 11, 112, 1, 114 },
                randomSet                                                                         }
                                                                                                  ;
            foreach (var test in tests)                                                           {
                Console.WriteLine($"Input:  {{{string.Join(", ", test)}}}")                       ;
                Console.WriteLine($"Output: {test.ArrangedFormNumbersDescending()}\r\n")          ;
                                                                                                  }
            Console.WriteLine("-- Press any key to exit --")                                      ;
            Console.ReadKey()                                                                     ;
                                                                                                  }
                                                                                                  }
    public static class ArrangeFormNumbersExtension                                               {
        public static string ArrangedFormNumbersAscending(this int[] nums)
            => string.Join("", nums.OrderBy(
                i => i,
                Comparer<int>.Create((x, y) =>
                    Convert.ToInt32(string.Join("", new[] { x, y })) - 
                    Convert.ToInt32(string.Join("", new[] { y, x })))))                           ;

        public static string ArrangedFormNumbersDescending(this int[] nums)
            => string.Join("", nums.OrderByDescending(
                i => i, 
                Comparer<int>.Create((x, y) => 
                    Convert.ToInt32(string.Join("", new[] { x, y })) - 
                    Convert.ToInt32(string.Join("", new[] { y, x })))))                           ;
                                                                                                  }
                                                                                                  }

Это правильно отформатированная версия:
using System;
using System.Collections.Generic;
using System.Linq;

namespace ArrangedFormNumbers
{
    static class Program
    {
        static void Main(string[] args)
        {
            var max = 50;
            var r = new Random();
            var randomSet = new int[max];

            for (int i = 0; i < max; i++)
            { 
                for (;;)
                {
                    var n = r.Next(1, 255);
                    if (!randomSet.Contains(n))
                    {
                        randomSet[i] = n;
                        break;
                    }
                }
            }

            var tests = new List<int[]>()
            {
                new[] { 1, 5, 67, 9 },
                new[] { 1, 5, 67, 94, 96, 91, 9 },
                new[] { 11, 112, 1, 114 },
                randomSet
            };


            foreach (var test in tests)
                Console.WriteLine($"Input:  {{{string.Join(", ", test)}}}\r\nOutput: {test.ArrangedFormNumbersDescending()}\r\n");

            Console.WriteLine("-- Press any key to exit --");
            Console.ReadKey();
        }
    }

    public static class ArrangeFormNumbersExtension
    {
        public static string ArrangedFormNumbersAscending(this int[] nums)
            => string.Join("", nums.OrderBy(
                i => i,
                Comparer<int>.Create((x, y) =>
                    Convert.ToInt32(string.Join("", new[] { x, y })) - Convert.ToInt32(string.Join("", new[] { y, x })))));

        public static string ArrangedFormNumbersDescending(this int[] nums)
            => string.Join("", nums.OrderByDescending(
                i => i, 
                Comparer<int>.Create((x, y) => 
                    Convert.ToInt32(string.Join("", new[] { x, y })) - Convert.ToInt32(string.Join("", new[] { y, x })))));
    }
}

Обновление: Добавлен генератор случайных чисел для тестового диапазона и максимального требования.

Выход:
Input:  {1, 5, 67, 9}
Output: 96751

Input:  {1, 5, 67, 94, 96, 91, 9}
Output: 99694916751

Input:  {11, 112, 1, 114}
Output: 114112111

Input:  {239, 196, 48, 208, 206, 94, 238, 246, 20, 81, 47, 115, 254, 144, 226, 45, 8, 249, 140, 53, 245, 190, 252, 135, 96, 63, 28, 110, 243, 143, 247, 146, 88, 13, 77, 18, 204, 142, 193, 34, 30, 148, 251, 228, 15, 170, 67, 149


PIEBALDconsult

-но тогда это уже не один лайнер. Где же в этом веселье"
Вы можете иметь либо одну линию, либо производительность; вы не можете иметь и то, и другое.

Graeme_Grant

Чистый или дублированный Код ... да...

Рейтинг:
1

Graeme_Grant

[Обновленный] Используя IComparer<T> метод от Решение 3, вот визуализация сортировки с использованием до девяти (9) алгоритмов сортировки: Пузырьковая сортировка[^], Гребень Вроде[^], Циклическая Сортировка[^], Вроде Гном [^], Сортировка Вставками [^], Чет-нечет сортировки[^], быстрая сортировка[^], Сортировка Выбора[^], Сортировка Шелла [^].

Я сделал их асинхронными, чтобы несколько могли работать одновременно и видеть, как они функционируют. Я закодировал действия цветом: синий = оценка, зеленый = замена, серый = неактивен. Наконец, существует значение задержки сна, которое можно установить перед запуском приложения, чтобы вы могли настроить его в соответствии с вашими потребностями.

Вот моя попытка, полностью рабочая версия, сделать решение "достаточно неоднозначным", чтобы удовлетворить одно из требований задачи:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace VisualSort {

public class CodeProjectComparer : IComparer<int> { int IComparer<int>.Compare(int a, int b) => Convert.ToInt32(string.Join("", new[] { a, b })) - Convert.ToInt32(string.Join("", new[] { b, a })); }

public enum SortType { Bubble, Comb, Cycle, Gnome, Insertion, OddEven, Quick, Selection, Shell }

static class Program { static object P = new object(); static int Q { get; set; } static int R { get; set; } static Dictionary<SortType, SortTracker> S = new Dictionary<SortType, SortTracker>(); static List<List<Position>> U = new List<List<Position>>();
static void Main(string[] a) { ucolr = Console.ForegroundColor; ecolr = ConsoleColor.Blue; scolr = ConsoleColor.Green; R = 50; Q = 100; Intro(); PromptUser("-- Press any key to begin --", true); MainAsync().GetAwaiter().GetResult(); PromptUser("-- Press any key to exit --"); }
static async Task MainAsync() { InitPos(); Add(SortType.Bubble, "Bubble Sort Descending"); Add(SortType.Insertion, "Insertion Sort"); Add(SortType.Quick, "Quick Sort"); Add(SortType.Shell, "Shell Sort Descending"); InitArea(); var a = InitTests(); for (int b = 0; b < a.Count; b++) { await ExecuteTestAsync(a[b], string.Format("Running Test: {0} of {1}...", b + 1, a.Count)); if (b < a.Count - 1) PromptUser("-- Press any key to run the next test --"); } }
static async Task ExecuteTestAsync(int[] a, string b) { ClearArea(S.Count); SetAreas(a); await Task.Delay(1000); WriteAt(new Position(5, upos), ucolr, b); await Task.WhenAll(S.Execute(a)); }
static void Add(SortType a, string b) { S.Add(a, new SortTracker(b, ucolr, ecolr, scolr, U[S.Count], new Position(23, 9 + S.Count * 10), Q, WriteAt)); }
static List<int[]> InitTests(int a = 50) { R = a; var b = new Random(); var c = new int[R]; for (int d = 0; d < R; d++) for (;;) { int e = b.Next(1, 255); if (!c.Contains(e)) { c[d] = e; break; } } return new List<int[]>(){new[]{1,5,67,9},new[]{1,5,67,94,96,91,9},new[]{11,112,1,114},new[]{4,45,46,43},new[]{23,232,235,233},new[]{102,1,36,12,21,79,170,9},new[]{3,12,306,12,21,190,170,90},c}; }
static int upos; static ConsoleColor ucolr { get; set; } static ConsoleColor ecolr { get; set; } static ConsoleColor scolr { get; set; }
static void SetAreas(int[] a) { foreach (var tracker in S) for (int b = 0; b < a.Length; b++) WriteAt(tracker.Value.Z[b], tracker.Value.W, a[b].ToString().PadLeft(5)); }
static void ClearArea(int a) { int b = 9; foreach (var tracker in S) { for (int c = 0; c < R; c++) WriteAt(tracker.Value.Z[c], tracker.Value.W, "     "); WriteAt(new Position(23, b), tracker.Value.W, "0".PadRight(5)); b += 10; } WriteAt(new Position(5, upos), Console.ForegroundColor, "".PadLeft(40)); }
static void Intro() { Console.WriteLine("CodeProject's Coding challenge: arrange numbers to form the largest possible integer"); Console.WriteLine(""); Console.WriteLine("This is a Visualualisaton of different sorting algorithms on number datasets\r\nthat meet the following requirements:"); Console.WriteLine(""); Console.WriteLine("1. Given a set of integers, arrange the integers so that the final integer\r\n   thus formed is the largest number possible."); Console.WriteLine("2. The list may contain up to 50 numbers, and each number will be less than\r\n   256 and positive."); Console.WriteLine(""); Console.WriteLine("There are a number of different sorting algorithms that can be toggled on/off\r\nin the MainAsync method before running."); Console.WriteLine(""); Console.WriteLine("NOTE: It is advisable to adjust the size of the console window to see all\r\nsorts in action at the same time."); Console.WriteLine(""); Console.WriteLine("Enjoy! :)"); Console.WriteLine(""); Console.WriteLine(""); }
static void InitPos() { int a = R < 11 ? R : 10; int b = R < 11 ? 1 : R / 10; for (int c = 0; c < 9; c++) U.Add(new List<Position>()); for (int d = 0; d < b; d++) for (int e = 0; e < a; e++) { int f = 3; foreach (var postion in U) { postion.Add(new Position((e * 5) + 5, d + f)); f += 10; } } }
static void InitArea() { upos = 2 + S.Count * 10; Console.CursorVisible = false; Console.Clear(); var a = Console.ForegroundColor; var b = Console.BackgroundColor; int c = 1, d = 9; foreach (var tracker in S) { Console.BackgroundColor = ConsoleColor.Blue; WriteAt(new Position(5, c), ConsoleColor.White, string.Format("  {0}", tracker.Value.P).PadRight(50)); Console.BackgroundColor = b; WriteAt(new Position(15, d), ConsoleColor.White, "Steps:"); c += 10; d += 10; } ConsoleBox(new Position(60, 3), 17, 8, ConsoleColor.White); Console.BackgroundColor = ConsoleColor.Blue; WriteAt(new Position(61, 4), ConsoleColor.White, " COLOUR LEGEND "); Console.BackgroundColor = b; WriteAt(new Position(64, 6), ucolr, "idle"); WriteAt(new Position(64, 7), ecolr, "Evaluating"); WriteAt(new Position(64, 8), scolr, "Changing"); Console.ForegroundColor = a; }
static void WriteAt(Position a, ConsoleColor b, string c) { lock (P) { Console.ForegroundColor = b; if (a != null) Console.SetCursorPosition(a.C, a.R); Console.Write(c); } }
static void PromptUser(string a, bool b = false) { WriteAt(b ? null : new Position(5, upos), Console.ForegroundColor, a); Console.ReadKey(); }
static void ConsoleBox(Position a, int b, int c, ConsoleColor d) { var e = Console.ForegroundColor; Console.OutputEncoding = Encoding.GetEncoding(866); Console.ForegroundColor = d; int f = b - 2; var g = string.Join("", Enumerable.Range(1, f).Select(h => "─")); var i = new StringBuilder().Append("┌").Append(g).Append("┐\n").ToString(); var j = new StringBuilder().Append("│").Append("".PadLeft(f)).Append("│\n").ToString(); var k = new StringBuilder().Append("└").Append(g).Append("┘").ToString(); Console.SetCursorPosition(a.C, a.R); Console.Write(i); for (int l = 1; l < c; l++) { Console.SetCursorPosition(a.C, a.R + l); Console.Write(j); } Console.SetCursorPosition(a.C, a.R + c - 1); Console.Write(k); Console.ForegroundColor = e; } }

public enum FeedbackType { Eval, Swap, Done }

public class Position { public Position(int c, int r) { C = c; R = r; } public int C { get; set; } public int R { get; set; } }

public class SortTracker { public SortTracker() { }
public SortTracker(string a, ConsoleColor b, ConsoleColor c, ConsoleColor d, List<Position> e, Position f, int g, Action<Position, ConsoleColor, string> h) { P = a; W = b; X = c; Y = d; Z = e; V = g; U = f; Writer = h; S = new[] { -1, -1 }; }
public string P { get; set; } public int Q { get; set; } public int[] R { get; set; } int[] S { get; } Position U; public int V { get; set; } public ConsoleColor W { get; set; } public ConsoleColor X { get; set; } public ConsoleColor Y { get; set; } public List<Position> Z { get; set; } public Action<Position, ConsoleColor, string> Writer { get; set; }
public void a0(int[] a) { R = a; Q = 0; S[0] = -1; S[1] = -1; }
public Task a1(int a, in


Рейтинг:
1

Graeme_Grant

Вот быстрая версия WPF MVVM, которую я собрал за обедом, используя целочисленный компаратор из моего другого решения (Решение 3).

Я использовал пользовательские SortableObservableCollection из расширенного ObservableCollection передача компаратора и обновление представления через систему привязки происходит при изменении порядка элементов.

Вот ViewModel & amp; вспомогательные классы:

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;

namespace WpfCodeChallenge
{
    public class CodeProjectComparer : IComparer<int>
    {
        int IComparer<int>.Compare(int x, int y) => (int)(Concat(x, y) - Concat(y, x));

        private Int64 Concat(Int32 x, Int32 y)
        {
            Int64 pow = 1;
            while (pow <= y) pow = ((pow << 2) + pow) << 1;
            return x * pow + y;
        }
    }

    public class SortableObservableCollection<T> : ObservableCollection<T>
    {
        public void SortDescending<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer)
        {
            ApplySort(Items.OrderByDescending(keySelector, comparer));
        }

        private void ApplySort(IEnumerable<T> sortedItems)
        {
            var sortedItemsList = sortedItems.ToList();
            foreach (var item in sortedItemsList)
                Move(IndexOf(item), sortedItemsList.IndexOf(item));
        }
    }

    public class MainViewModel : INotifyPropertyChanged
    {
        public MainViewModel()
        {
            Parse("94,9,99,98,111,11,112,1");
        }

        private IComparer<int> comparer = new CodeProjectComparer();
        public event PropertyChangedEventHandler PropertyChanged;

        public SortableObservableCollection<int> DataSet { get; set; }
            = new SortableObservableCollection<int>();

        private string csvValues;
        public string CsvValues { get { return csvValues; } set { Parse(value); } }

        private void Parse(string value)
        {
            csvValues = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("CsvValues"));

            try
            {
                var values = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                          .Select(x => Convert.ToInt32(x));
                if (values.Any())
                {
                    DataSet.Clear();
                    foreach (var val in values)
                        DataSet.Add(val);
                    DataSet.SortDescending(x => x, comparer);
                }
            }
            catch { }
        }
    }
}

Вот вид (не используется код позади):
<Window x:Class="WpfCodeChallenge.MainWindow" Height="350" Width="525"

		xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 

		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

		xmlns:vm="clr-namespace:WpfCodeChallenge"

		Title="Weekly Coding Challenge Code Project: Arrange Numbers">
	<Window.DataContext>
		<vm:MainViewModel/>
	</Window.DataContext>
	<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="50">
		<Grid.RowDefinitions>
			<RowDefinition Height="Auto"/>
			<RowDefinition MinHeight="100"/>
		</Grid.RowDefinitions>
		<Grid.ColumnDefinitions>
			<ColumnDefinition Width="Auto"/>
			<ColumnDefinition MinWidth="200"/>
		</Grid.ColumnDefinitions>
		<TextBlock Text="Input csv numeric values:" Margin="4 10" 

                   VerticalAlignment="Top"/>
		<TextBox Text="{Binding CsvValues, UpdateSourceTrigger=PropertyChanged, Delay=200}" 

				 TextWrapping="Wrap" MaxLines="1" Grid.Column="1" Margin="0 10" 

                 VerticalAlignment="Top"/>
		<TextBlock Text="Output(sorted)" Grid.Row="1" Margin="4 10" MinHeight="100"/>
		<ListBox ItemsSource="{Binding DataSet}" Grid.Row="1" Grid.Column="1" Margin="0 10"

				 ScrollViewer.HorizontalScrollBarVisibility="Disabled"

				 ScrollViewer.VerticalScrollBarVisibility="Auto">
			<ListBox.ItemsPanel>
				<ItemsPanelTemplate>
                    <WrapPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
			</ListBox.ItemsPanel>
		</ListBox>
	</Grid>
</Window>

Обновление: Я обнаружил проблему с обычаем SortableObservableCollection - он неправильно обрабатывает дубликаты. Поэтому, чтобы сохранить код простым, я перешел на CollectionViewSorce в XAML. Чтобы применить пользовательскую сортировку с помощью CodeProjectComparer, Я добавил ручную проводку компаратора к CollectionViewSorce.CustomSort собственность. Это не может быть подключено в Xaml. Кроме того, как CollectionViewSorce находится в Xaml, нам нужно дождаться, пока он загрузится. Поэтому мы делаем это в Listbox.Loaded событие.

Вот пересмотренная версия CodeProjectComparer и MainViewModel занятия:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;

namespace WpfCodeChallenge
{
    public class CodeProjectComparer : IComparer
    {
        public int Compare(object x, object y) 
            => (int)(Concat((int)y, (int)x) - Concat((int)x, (int)y));

        private Int64 Concat(Int32 x, Int32 y)
        {
            Int64 pow = 1;
            while (pow <= y) pow = ((pow << 2) + pow) << 1;
            return x * pow + y;
        }
    }

    public class MainViewModel : INotifyPropertyChanged
    {
        public MainViewModel()
        {
            Parse("94,9,99,98,111,11,112,1");
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public ObservableCollection<int> DataSet { get; set; }
            = new ObservableCollection<int>();

        private string csvValues;
        public string CsvValues { get { return csvValues; } set { Parse(value); } }

        private void Parse(string value)
        {
            csvValues = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("CsvValues"));

            try
            {
                var values = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
                                  .Select(x => Convert.ToInt32(x));
                if (values.Any())
                {
                    DataSet.Clear();
                    foreach (var val in values) DataSet.Add(val);
                }
            }
            catch { }
        }
    }
}

Вот такой вид:
<Window x:Class="WpfCodeChallenge.MainWindow" Height="350" Width="525"

		xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 

		xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

		xmlns:vm="clr-namespace:WpfCodeChallenge"

		Title="Weekly Coding Challenge Code Project: Arrange Numbers">
	<Window.DataContext>
		<vm:MainViewModel/>
	</Window.DataContext>
	<Window.Resources>
		<CollectionViewSource x:Key="CsvData" Source="{Binding DataSet}" 

                                      IsLiveSortingRequested="True"/>
	</Window.Resources>
	<Grid HorizontalAlignment="Stretch" VerticalAlignment="Center" Margin="50">
		<Grid.RowDefinitions>
			<RowDefinition Height="Auto"/>
			<RowDefinition MinHeight="100"/>
		</Grid.RowDefinitions>
		<Grid.ColumnDefinitions>
			<ColumnDefinition Width="Auto"/>
			<ColumnDefinition MinWidth="200"/>
		</Grid.ColumnDefinitions>
		<TextBlock Text="Input csv numeric values:" Margin="4 10" 

				   VerticalAlignment="Top"/>
		<TextBox Text="{Binding CsvValues, UpdateSourceTrigger=PropertyChanged, Delay=200}" 

				 TextWrapping="Wrap" MaxLines="1" Grid.Column="1" Margin="0 10" 

				 VerticalAlignment="Top"/>
		<TextBlock Text="Output(sorted)" Grid.Row="1" Margin="4 10" MinHeight="100"/>
		<ListBox ItemsSource="{Binding Source={StaticResource CsvData}}" 

				 Grid.Row="1" Grid.Column="1" Margin="0 10" Loaded="OnLoaded"

				 ScrollViewer.HorizontalScrollBarVisibility="Disabled"

				 ScrollViewer.VerticalScrollBarVisibility="Auto">
			<ListBox.ItemsPanel>
				<ItemsPanelTemplate>
					<WrapPanel Orientation="Horizontal"/>
				</ItemsPanelTemplate>
			</ListBox.ItemsPanel>
		</ListBox>
	</Grid>
</Window>

И, наконец, вот код представления-позади:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace WpfCodeChallenge
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            ((ListCollectionView)((ListBox)sender).ItemsSource).CustomSort
                = new CodeProjectComparer();
        }
    }
}

Обновление №2: Сегодня я работал над TreeView, где требовалась пользовательская сортировка на уровне ветвей, и понял, что здесь можно использовать тот же метод. Итак, вот еще одна версия, использующая ValueConverter, устраняющая необходимость подключения события в коде представления и ViewModel.

Теперь мы привязываем список непосредственно к пользовательскому вводу. Однострочный преобразователь значений с помощью Linq отфильтрует недопустимые символы из входной строки, преобразует ее в список и применит сортировку через CollectionViewSource.

Вот пересмотренн


Рейтинг:
0

Bryian Tan

Обновлено 1/21. Очевидно, что предыдущее решение имеет недостаток. Спасибо Graeme_Grant за то, что указал на это. Я изменил решение, чтобы добавить в него некоторые избыточные шаги, такие как группировка по первой цифре, а затем сортировка по группам. После этого объедините группу в строку. Во всяком случае, я думаю, что ключ здесь-это компаратор<int>. Я думаю, что решение от Graeme_Grant является выдающимся.

------
я думаю, что это должно сделать это. Сначала разделите целое число на основание 10 в степени длины целого числа (веса), затем отсортируйте его по весу и объедините выходные данные в строку с помощью string.метод соединения.

логика

var testData = new List<int[]>()
            {
                new[] { 1, 5, 67, 6, 9, 91 },
                new[] { 81, 8, 8111, 811 },
                new[] { 1,102,0,10,1, 60, 61 },
                new[] { 2,0,11,10,69,79,4 },
                new[] { 102,01,36,12,21,79,970,9 },
                new[] { 3,012,306,12,21,790,970,90 },
                new[] { 10, 5, 67, 97, 8 },
                new[] { 70, 71, 102, 1, 10,8,80, 9,91, 90, 900, 9000, 2, 4, 1112, 1100,11,99}
            };

            foreach (var d in testData)
            {
                var result = string.Join("", d.GroupBy(x => x.ToString().Substring(0, 1), (number, subList) => new
                {
                    Number = number,
                    SubList = subList.OrderByDescending(x => x, 
                    Comparer<int>.Create((a, b) => int.Parse(string.Format("{0}{1}", a, b)) - int.Parse(string.Format("{0}{1}", b, a))))

                }).OrderByDescending(x => x.Number).SelectMany(s => s.SubList));

                Console.WriteLine("input: {0} ", string.Join(",", d));
                Console.WriteLine("output: {0} ", result);
                Console.WriteLine();
            }

            Console.WriteLine();
            Console.ReadLine();


Выход
input: 1,5,67,6,9,91
output: 9-91-67-6-5-1

input: 81,8,8111,811
output: 8-81-811-8111

input: 1,102,0,10,1,60,61
output: 61-60-1-1-102-10-0

input: 2,0,11,10,69,79,4
output: 79-69-4-2-11-10-0

input: 102,1,36,12,21,79,970,9
output: 9-970-79-36-21-12-1-102

input: 3,12,306,12,21,790,970,90
output: 970-90-790-3-306-21-12-12

input: 10,5,67,97,8
output: 97-8-67-5-10

input: 70,71,102,1,10,8,80,9,91,90,900,9000,2,4,1112,1100,11,99
output: 9-99-91-90-900-9000-8-80-71-70-4-2-1112-1-11-1100-102-10


Graeme_Grant

попробуйте этот набор: { 1, 5, 67, 94, 96, 91, 9 }

Bryian Tan

ха-ха, да, слишком хорошо, чтобы быть правдой, не очень хорошо работает с 81,8,91,9

Graeme_Grant

да... Я тоже допустил ошибку с моим первоначальным комментарием наверху... [редактировать] Я так понимаю, именно поэтому Крис выложил это как вызов. ;)

Graeme_Grant

Эй, Брайан, Спасибо за комментарии в вашем решении. Для меня это большая честь. :)

Patrice T

Я получаю
102 1 36 12 21 79 970 9
9 970 79 36 21 12 1 102

3 12 306 12 21 790 970 90
970 90 790 3 306 21 12 12

Рейтинг:
0

Peter Leow

Решил использовать это как упражнение, чтобы сблизиться с моей новообретенной любовью к питону. Решение простое, я имею в виду. Просто дополните список целых чисел нулями до максимального количества цифр, доступных в списке, отсортируйте их в порядке убывания, а затем объедините исходный список целых чисел в соответствии с этим порядком. Оказалось, что я весело флиртую со списком и словарем на Python, результат показан:

"""
largest_possible_integer.py
by Peter Leow

Coding challenge: arrange numbers to form the largest possible integer

"""

import random

# Create a list of x number of random integers from 0 to 255
x = 50
list_int = random.sample(range(0,256), x)
print("List of {} positive integers (0 to 255): {}".format(x, list_int))

# Find the max integer in the list
max_int = max(list_int)
print("Max integer = {}".format(max_int))

# Find number of digits for this max integer
max_digit_count = len(str(max_int))
print("Most number of digits = {}".format(max_digit_count))

# Create a dictionary with list elements as keys and 
# their zero-padded values up to max_digit_count as values
dict_int = {}
for int in (list_int):
    dict_int[int] =  int * 10**(max_digit_count - len(str(int)))
print("Dictionary = {}".format(dict_int))

# Sort the original integer list based on the descending order
# of their padded values in the dictionary 
sorted_list_int = sorted(list_int, key=dict_int.__getitem__, reverse=True)

print("Sorted integer list to form the largest integer = {}".format(sorted_list_int))

largest_integer = ''.join(str(int) for int in sorted_list_int)

print("The largest integer is {}".format(largest_integer))
Попробуйте это сделать вот так игровая площадка[^]. Измените значение x и получайте удовольствие! Отказ от ответственности: переполнение на свой страх и риск!
Два примера выходных данных:
List of 10 positive integers (0 to 255): [93, 185, 191, 48, 209, 26, 36, 42, 25, 107]
Max integer = 209
Most number of digits = 3
Dictionary = {48: 480, 209: 209, 42: 420, 36: 360, 25: 250, 185: 185, 26: 260, 107: 107, 93: 930, 191: 191}
Sorted integer list to form the largest integer = [93, 48, 42, 36, 26, 25, 209, 191, 185, 107]
The largest integer is 934842362625209191185107
и
List of 50 positive integers (0 to 255): [26, 2, 246, 241, 107, 92, 215, 173, 119, 176, 156, 235, 125, 165, 129, 13, 19, 74, 227, 81, 248, 159, 102, 180, 90, 63, 123, 232, 217, 133, 224, 219, 98, 57, 95, 179, 245, 140, 151, 68, 254, 250, 117, 203, 9, 52, 222, 34, 41, 11]
Max integer = 254
Most number of digits = 3
Dictionary = {129: 129, 2: 200, 107: 107, 133: 133, 9: 900, 11: 110, 140: 140, 13: 130, 19: 190, 151: 151, 26: 260, 156: 156, 159: 159, 34: 340, 165: 165, 41: 410, 173: 173, 176: 176, 179: 179, 180: 180, 57: 570, 117: 117, 52: 520, 68: 680, 74: 740, 203: 203, 81: 810, 215: 215, 217: 217, 90: 900, 219: 219, 92: 920, 222: 222, 95: 950, 224: 224, 98: 980, 227: 227, 102: 102, 232: 232, 63: 630, 235: 235, 241: 241, 245: 245, 246: 246, 119: 119, 248: 248, 250: 250, 123: 123, 125: 125, 254: 254}
Sorted integer list to form the largest integer = [98, 95, 92, 90, 9, 81, 74, 68, 63, 57, 52, 41, 34, 26, 254, 250, 248, 246, 245, 241, 235, 232, 227, 224, 222, 219, 217, 215, 203, 2, 19, 180, 179, 176, 173, 165, 159, 156, 151, 140, 133, 13, 129, 125, 123, 119, 117, 11, 107, 102]
The largest integer is 9895929098174686357524134262542502482462452412352322272242222192172152032191801791761731651591561511401331312912512311911711107102
++ + + + [Раунд 2]+++++

Насторожил пполиморф. Нашел озорство, которое вызвано одиночными цифрами. Увидеть исправленный код:
"""
largest_possible_integer.py
by Peter Leow

Coding challenge: arrange numbers to form the largest possible integer

"""

import random

# Create a list of x number of random integers from 0 to 255
x = 50
# list_int = random.sample(range(0,256), x)

list_int = [26, 2, 246, 241, 107, 92, 215, 173, 119, 176, 156, 235, 125, 165, 129, 13, 19, 74, 227, 81, 248, 159, 102, 180, 90, 63, 123, 232, 217, 133, 224, 219, 98, 57, 95, 179, 245, 140, 151, 68, 254, 250, 117, 203, 9, 52, 222, 34, 41, 11]

print("List of {} positive integers (0 to 255): {}".format(x, list_int))

# Find the max integer in the list
max_int = max(list_int)
print("Max integer = {}".format(max_int))

# Find number of digits for this max integer
max_digit_count = len(str(max_int))
print("Most number of digits = {}".format(max_digit_count))

# Create a dictionary with list elements as keys and 
# their zero-padded values up to max_digit_count as values
dict_int = {}
for int in (list_int):
    length = len(str(int))
    
    if length == 1: # if single digit
        # make it the max in its range e.g. 2 to 299
        dict_int[int] =  (int + 1) * 10**(max_digit_count - length) - 1 
    else:
        dict_int[int] =  int * 10**(max_digit_count - length)
        
print("Dictionary = {}".format(dict_int))

# Sort the original integer list based on the descending order
# of their padded values in the dictionary 
sorted_list_int = sorted(list_int, key=dict_int.__getitem__, reverse=True)

print("Sorted integer list to form the largest integer = {}".format(sorted_list_int))

largest_integer = ''.join(str(int) for int in sorted_list_int)

print("The largest integer is {}".format(largest_integer))
Проверить это: Питон Playround[^] и выход:
List of 50 positive integers (0 to 255): [26, 2, 246, 241, 107, 92, 215, 173, 119, 176, 156, 235, 125, 165, 129, 13, 19, 74, 227, 81, 248, 159, 102, 180, 90, 63, 123, 232, 217, 133, 224, 219, 98, 57, 95, 179, 245, 140, 151, 68, 254, 250, 117, 203, 9, 52, 222, 34, 41, 11]
Max integer = 254
Most number of digits = 3
Dictionary = {129: 129, 2: 299, 107: 107, 133: 133, 9: 999, 11: 110, 140: 140, 13: 130, 19: 190, 151: 151, 26: 260, 156: 156, 159: 159, 34: 340, 165: 165, 41: 410, 173: 173, 176: 176, 179: 179, 180: 180, 57: 570, 117: 117, 52: 520, 68: 680, 74: 740, 203: 203, 81: 810, 215: 215, 217: 217, 90: 900, 219: 219, 92: 920, 222: 222, 95: 950, 224: 224, 98: 980, 227: 227, 102: 102, 232: 232, 63: 630, 235: 235, 241: 241, 245: 245, 246: 246, 119: 119, 248: 248, 250: 250, 123: 123, 125: 125, 254: 254}
Sorted integer list to form the largest integer = [9, 98, 95, 92, 90, 81, 74, 68, 63, 57, 52, 41, 34, 2, 26, 254, 250, 248, 246, 245, 241, 235, 232, 227, 224, 222, 219, 217, 215, 203, 19, 180, 179, 176, 173, 165, 159, 156, 151, 140, 133, 13, 129, 125, 123, 119, 117, 11, 107, 102]
The largest integer is 9989592908174686357524134226254250248246245241235232227224222219217215203191801791761731651591561511401331312912512311911711107102

++ + + + [раунд 3]+++++
Я вернулся. Это было время моего сна после напряженного дня подготовки к наступающему Китайскому Новому году. Понимая, что дискуссии, которые вливаются в него, и интересы, которые его порождают, не могут просто уйти от него. Потратьте некоторое время, чтобы поразмыслить над тем, как исправить это одноразрядное озорство. Кажется, на этот раз я все понял. Видеть это:
"""
largest_possible_integer.py
by Peter Leow

Coding challenge: arrange numbers to form the largest possible integer

"""

import random

# Create a list of x number of random integers from 0 to 255
x = 50
# list_int = random.sample(range(0,256), x)


list_int = [26, 2, 246, 241, 107, 92, 215, 173, 119, 176, 156, 235, 125, 165, 129, 13, 19, 74, 227, 81, 248, 159, 102, 180, 90, 63, 123, 232, 217, 133, 224, 219, 98, 57, 95, 179, 245, 140, 151, 68, 254, 250, 117, 203, 9, 52, 222, 34, 41, 11]

print("List of {} positive integers (0 to 255): {}".format(x, list_int))

# Find the max integer in the list
max_int = max(list_int)
print("Max integer = {}".format(max_int))

# Find number of digits for this max integer
max_digit_count = len(str(max_int))
print("Most number of digits = {}".format(max_digit_count))

# Create a dictionary with list elements as keys and 
# their zero-padded values up to max_digit_count as values
dict_int = {}
for int in (list_int):
    length = len(str(int))
    
    if length == 1:
        
        temp = int
        
        for i in range(1, max_digit_count):
            temp += int * 10**i
        
        dict_int[int] = temp
    else:
        dict_int[int] =  int * 10**(max_digit_count - length)
        
print("Dictionary = {}".format(dict_int))

# Sort the original integer list based on the descending order
# of their padded values in the dictionary 
sorted_list_int = sorted(list_int, key=dict_int.__getitem__, reverse=True)

print("Sorted integer list to form the largest integer = {}".format(sorted_list_int))

largest_integer = ''.join(str(int) for int in sorted_list_int)

print("The largest integer is {}".format(largest_integer))
Выход таков:
List of 50 positive integers (0 to 255): [26, 2, 246, 241, 107, 92, 215, 173, 119, 176, 156, 235, 125, 165, 129, 13, 19, 74, 227, 81, 248, 159, 102, 180, 90, 63, 123, 232, 217, 133, 224, 219, 98, 57, 95, 179, 245, 140, 151, 68, 254, 250, 117, 203, 9, 52, 222, 34, 41, 11]
Max integer = 254
Most number of digits = 3
Dictionary = {129: 129, 2: 222, 107: 107, 133: 133, 9: 999, 11: 110, 140: 140, 13: 130, 19: 190, 151: 151, 26: 260, 156: 156, 159: 159, 34: 340, 165: 165, 41: 410, 173: 173, 176: 176, 179: 179, 180: 180, 57: 570, 117: 117, 52: 520, 68: 680, 74: 740, 203: 203, 81: 810, 215: 215, 217: 217, 90: 900, 219: 219, 92: 920, 222: 222, 95: 950, 224: 224, 98: 980, 227: 227, 102: 102, 232: 232, 63: 630, 235: 235, 241: 241, 245: 245, 246: 246, 119: 119, 248: 248, 250: 250, 123: 123, 125: 125, 254: 254}
Sorted integer list to form the largest integer = [


Patrice T

Последний набор
Я думаю, что 2 неуместно, он должен быть помещен около 222.

Peter Leow

Почему?

Patrice T

Потому что
224, 222, 219, 217, 215, 203, 2 -> 2242222192172152032
и
224, 222, 2, 219, 217, 215, 203 -> 2242222219217215203

Peter Leow

Понял, спасибо.

Peter Leow

Спасибо за обратную связь. Взглянул еще раз. Нашли виновника, которым являются все однозначные цифры. Поставьте их на максимум в соответствующих диапазонах, например 2 = & gt; 299. Решить ее.

Patrice T

"например, 2 = & gt; 299. Решить ее."
Боюсь, что обивка еще сложнее.
Посмотрите на позицию 2 в предыдущем комментарии

Peter Leow

Ты опять прав. Я оставляю это дело. Надо заняться другими делами.

PIEBALDconsult

Следует избегать набивки.

Peter Leow

Отмеченный. Спасибо.

Patrice T

Зависит от используемого метода.
Как вы сортируете 242 и 24 без заполнения ?

PIEBALDconsult

Согласно моему второму компаратору. Никаких прокладок или других манипуляций со строками не требуется. Просто символ сравнивает и целое число сравнивает, чтобы разорвать связи.

Patrice T

Обратите внимание, что раунд 2 все еще ошибочен.
2 идите рядом с 222

PIEBALDconsult

Примеры?
2 предшествует 222

Patrice T

В вашем последнем сете
"2, 26, 254, 250, 248, 246, 245, 241, 235, 232, 227, 224, 222"
правильные ответы таковы
"26, 254, 250, 248, 246, 245, 241, 235, 232, 227, 224, 222, 2"
"26, 254, 250, 248, 246, 245, 241, 235, 232, 227, 224, 2, 222"

PIEBALDconsult

Шахта производит:
26 254 250 248 246 245 241 235 232 227 224 2 222

Patrice T

ОК выход исправлен.

Patrice T

Если я понимаю ваш метод заполнения, он терпит неудачу при таких сложных значениях, как {242, 24]

PIEBALDconsult

Шахта производит:
242 24 ==> 24 242

Patrice T

Правильный ответ.
В раунде 3 ваш код, кажется, набирает от 24 до 240, что должно привести к 242 24, поэтому я сомневаюсь.

PIEBALDconsult

Мой вообще не прокладывает, я думаю, что вы ответили не на тот плакат.
Если заполнение сделано (и это убьет производительность), то при сравнении 24 с 242 24 должно быть заполнено до 244-последняя цифра более короткого значения должна повторяться достаточно раз, чтобы строки были равны по длине.

Patrice T

ОППС мой плохой, неправильный плакат.
"последняя цифра более короткого значения должна повторяться достаточно раз, чтобы строки были равны по длине."
На самом деле неверное предположение, если вы попробуете 24, 242, 243, то оно должно отсортироваться до 243 24 242

PIEBALDconsult

Ага... хм...
Ооочень ... используйте ведущие символы из более длинного значения, чтобы "дополнить" более короткое значение...

Patrice T

Поскольку заполнение интересно только тогда, когда оба значения имеют одинаковое начало, я заполняю значение, повторяя его. И я прокладываю до максимальной длины+1.
24, 242, 243 дополняются до 2424, 2422, 2432, тогда сортировка очевидна.

PIEBALDconsult

Только что опубликовал еще один компаратор, который показывает другую технику - хотя я все еще ищу технику без манипулирования строками.

PIEBALDconsult

Ну, вам нужно только "pad", как только вы определите, что эти два значения идентичны до длины более короткого-нет необходимости "pad" до этого.

Patrice T

Да, это полезно только тогда, когда вы не можете отличить друг от друга на основе более короткой длины.
Всегда обивка или нет - это вопрос дизайнерского решения.

Graeme_Grant

Я объяснил это выше в решении 3.

{94, 9} = 949 - 994 = -45, измените на {9, 94}. Однако, {1, 112} = 1112 - 1121 = -9, правильный порядок - {112, 1}.

PIEBALDconsult

Да, и моя тоже
94 9 1 112 ==> 9 94 112 1

Graeme_Grant

Я написал вам, но на самом деле был для Питера (и других, кто мог бы подчиниться). :)

PIEBALDconsult

А, ладно.

Peter Leow

Привет, ребята. Извините, что заставил вас ждать. Я только что заметил возникшую здесь дискуссию и не могу просто лечь спать. Быстро все обдумал и получил третью версию. Проверьте это и дайте мне свой взгляд. Но мне нужно лечь спать, чтобы завтра не опоздать на работу.

Graeme_Grant

Хорошо выглядит Питер ... 2 и 222 равны, так что порядок не важен. Результат будет зависеть от используемого алгоритма.

2: 45 утра здесь, так что поймите, что вы чувствуете. :)

PIEBALDconsult

2 и 222 равны, но 20 и 200-нет, поэтому я даю более короткое значение приоритета всякий раз, когда мое первое сравнение говорит, что они равны.

Graeme_Grant

да, "20"+"200" != "200"+"20" но "2"+"222" = "222"+"2". :)

PIEBALDconsult

Ах, теперь это упростило бы ситуацию (для тех, кто хочет использовать манипуляции со строками); вместо того чтобы "заполнять" более короткое значение, просто сравните две возможные конкатенации. : D это гораздо более прямолинейно.

Я только что опубликовал новый компаратор, который делает это. Кажется, это работает, но я хочу избежать манипуляций со строками. У меня на уме что-то странное...

Graeme_Grant

Ладно, ладно, ты не хочешь использовать струны... Немного подумав, я обновил решение 3 (см. Нижний раздел) с рассчитанной версией только для вас. Тот же принцип проектирования все еще применим... ;)

PIEBALDconsult

Нет, я действительно хочу использовать строки, вы должны использовать строки, но следует избегать манипуляции строками.

Graeme_Grant

Посмотрите еще раз, в "посвященном PIEBALDConsult" нет строк, используемых новым компаратором в решении 3 (посмотрите вниз в нижней части решения, последнее обновление).

Graeme_Grant

Я только что еще раз взглянул на ваш код и заметил, что он "полностью строковый", но выше вы упомянули "я хочу избежать манипуляций со строками"... Мне все еще нравится Linq над вашей реализацией SortedList. Оба используют алгоритм быстрой сортировки Microsoft под прикрытием. По крайней мере, с Linq вам нужно только один раз повторить список - гораздо чище и эффективнее. ;)

PIEBALDconsult

Правильно, никаких строковых манипуляций - таких как конкатенция и подстрока, я даже не хочу использовать сравнение строк. У меня есть один индекс на каждое значение, определяющий целочисленность, и я хотел бы его исключить.
Вы можете иметь строки, но не манипулировать ими.

Graeme_Grant

Да... Вот почему я посвятил вам только целочисленное решение. Конкатенация в новом компараторе (решение 3) - это не конкатенация строк, а метод целочисленного расширения, который представляет собой двоичное слияние двух чисел, соединяющих или "Конкатенирующих" два числа в одно Int64 точно так же, как это сделала бы конкатенация строк. ;)

Graeme_Grant

Я только что опубликовал расчетную версию своего компаратора. Я думаю, что это более чистый способ сделать то, что вы пытались сделать.

Patrice T

Привет Питер,
Насколько я понимаю, вы заполняете 3-й раунд, это неправильно.
если вы попробуете 24, 242, 243, он должен отсортироваться до 243 24 242, но я думаю, что вы получите 243 242 24.

Peter Leow

Я пойду с PIEBALDconsult.