Комбинаторика php

bubblegumoff

Новичок
Здравствуйте! Искал в инете, но так и не смог найти толковых ответов..
Несколько дней уже ломаю голову.
Есть массив

$array = array("one", "two", "three");

Нужно вывести все возможные варианты в новый массив с указанием числа создаваемых фраз. Например

$k = 4;

$new_array = array(
array("one", "one", "one", "one"),
array("one", "one", "one", "two"),
array("one", "one", "one", "three"),
array("one", "one", "one", "four"),
array("one", "one", "two", "one"),
array("one", "one", "two", "two"),
array("one", "one", "two", "three"),
array("one", "one", "two", "four"),
array("one", "one", "three", "one"),
array("one", "one", "three", "two"),
array("one", "one", "three", "three"),
array("one", "one", "three", "four"),
array("one", "one", "four", "one"),
array("one", "one", "four", "two"),
array("one", "one", "four", "three"),
array("one", "one", "four", "four")
...
...
);

И заканчивается, соответственно, как-то так

$new_array = array(
...
...
array("four", "four", "three", "three"),
array("four", "four", "three", "four"),
array("four", "four", "four", "one"),
array("four", "four", "four", "two"),
array("four", "four", "four", "three"),
array("four", "four", "four", "four")
)
 

bubblegumoff

Новичок
function pc_permute($items, $perms = array()){
if (empty($items)) {
$return = array($perms);
} else {
$return = array();
for ($i = count($items) - 1; $i >= 0; --$i) {
$newitems = $items;
$newperms = $perms;
list($foo) = array_splice($newitems, $i, 1);
array_unshift($newperms, $foo);
$return = array_merge($return, $this->pc_permute($newitems, $newperms));
}
}
return $return;
}

И

$array = Array();
$array[1] = $main_array = array ('a', 'b', 'c', 'd', 'e', 'f');
$size = sizeof($array[1]);

$arr_name = 1;
for ($count = 2; $count <= $size; $count++) {

$this_size = sizeof($array[$arr_name]);
$arr_name++;
for ($i = 0; $i < $this_size; $i++) {
$gg = $array[($arr_name-1)][$i];
for ($x = 0; $x < $size; $x++) {
$array[$arr_name][] = $gg . $array[1][$x];
}

}
$main_array = array_merge($main_array, $array[$arr_name]);
if ($arr_name > 2)
unset($array[($arr_name-1)]);
}
unset($array[$arr_name]);
print_r($main_array);

Это лишь парочка из многих вариантов, которые я перепробовал. За эту бессонную ночь я понял, что самым оптимальным вариантом для меня будет всё прогонять через mysql. Т.к. комбинации будут и по 12-15 слов
 

bubblegumoff

Новичок
Спасибо, но это немного не то. Как уже написал, оптимальным вариантом будет через mysql всё записывать. Ибо, комбинации из 15 слов это очень много. А когда вариантов слов около 1000, то это просто нереально :)
 

WMix

герр M:)ller
Партнер клуба
интересна экономическая состовляющая, или как можно монетизировать комбинации из 15 слов
 

WMix

герр M:)ller
Партнер клуба
глядя на твой первый пост
array("one", "one", "one", "one"),
...
array("four", "four", "four", "four")
хочу предположить что тебе не нужна комбинаторика, просто переводи любое число (какую по счету комбинацию необходимо) в X-ричную систему и замени каждую цифру своим словом
PHP:
function get($nr, $k){
  $arr = ['one', 'two', 'three',  'four'];
  return array_map(function($n) use ($arr){
    return $arr[$n];
  }, str_split(substr(str_pad( base_convert($nr, 10, count($arr)),$k, '0', STR_PAD_LEFT), $k * -1)));
}
print_r(get(14, 4));
Под это дело выделится 500+ впс :)
мне 10% от сэкономленных
 

bubblegumoff

Новичок
глядя на твой первый пост

хочу предположить что тебе не нужна комбинаторика, просто переводи любое число (какую по счету комбинацию необходимо) в X-ричную систему и замени каждую цифру своим словом
PHP:
function get($nr, $k){
  $arr = ['one', 'two', 'three',  'four'];
  return array_map(function($n) use ($arr){
    return $arr[$n];
  }, str_split(substr(str_pad( base_convert($nr, 10, count($arr)),$k, '0', STR_PAD_LEFT), $k * -1)));
}
print_r(get(14, 4));

мне 10% от сэкономленных
Крайне любопытная функция. Я немного переделал

PHP:
function get($nr, $numbers_count){
    $arr = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen'];
    return array_map(function($k) use ($arr){
        return $arr[$k];
    }, str_split(substr(str_pad( base_convert($nr, $numbers_count, count($arr)),count($arr), '0', STR_PAD_LEFT), count($arr) * -1)));
}

$numbers_count = 15;
for($x = 0; $x < $numbers_count; $x++){
    print_r(get($x, $numbers_count));
}
Однако, всё равно не могу получить желаемого результата.

Вот получаемые мною массивы. Тут нет значений массива после 10 значения

Код:
Array
(
    [0] => one
    [1] => one
    [2] => one
    [3] => one
    [4] => one
    [5] => one
    [6] => one
    [7] => one
    [8] => one
    [9] => one
    [10] => one
    [11] => one
    [12] => one
    [13] => one
    [14] => one
)
Array
(
    [0] => one
    [1] => one
    [2] => one
    [3] => one
    [4] => one
    [5] => one
    [6] => one
    [7] => one
    [8] => one
    [9] => one
    [10] => one
    [11] => one
    [12] => one
    [13] => one
    [14] => two
)
Array
(
    [0] => one
    [1] => one
    [2] => one
    [3] => one
    [4] => one
    [5] => one
    [6] => one
    [7] => one
    [8] => one
    [9] => one
    [10] => one
    [11] => one
    [12] => one
    [13] => one
    [14] => three
)
Array
(
    [0] => one
    [1] => one
    [2] => one
    [3] => one
    [4] => one
    [5] => one
    [6] => one
    [7] => one
    [8] => one
    [9] => one
    [10] => one
    [11] => one
    [12] => one
    [13] => one
    [14] => four
)
Array
(
    [0] => one
    [1] => one
    [2] => one
    [3] => one
    [4] => one
    [5] => one
    [6] => one
    [7] => one
    [8] => one
    [9] => one
    [10] => one
    [11] => one
    [12] => one
    [13] => one
    [14] => five
)
Array
(
    [0] => one
    [1] => one
    [2] => one
    [3] => one
    [4] => one
    [5] => one
    [6] => one
    [7] => one
    [8] => one
    [9] => one
    [10] => one
    [11] => one
    [12] => one
    [13] => one
    [14] => six
)
Array
(
    [0] => one
    [1] => one
    [2] => one
    [3] => one
    [4] => one
    [5] => one
    [6] => one
    [7] => one
    [8] => one
    [9] => one
    [10] => one
    [11] => one
    [12] => one
    [13] => one
    [14] => seven
)
Array
(
    [0] => one
    [1] => one
    [2] => one
    [3] => one
    [4] => one
    [5] => one
    [6] => one
    [7] => one
    [8] => one
    [9] => one
    [10] => one
    [11] => one
    [12] => one
    [13] => one
    [14] => eight
)
Array
(
    [0] => one
    [1] => one
    [2] => one
    [3] => one
    [4] => one
    [5] => one
    [6] => one
    [7] => one
    [8] => one
    [9] => one
    [10] => one
    [11] => one
    [12] => one
    [13] => one
    [14] => nine
)
Array
(
    [0] => one
    [1] => one
    [2] => one
    [3] => one
    [4] => one
    [5] => one
    [6] => one
    [7] => one
    [8] => one
    [9] => one
    [10] => one
    [11] => one
    [12] => one
    [13] => one
    [14] => ten
)
Array
(
    [0] => one
    [1] => one
    [2] => one
    [3] => one
    [4] => one
    [5] => one
    [6] => one
    [7] => one
    [8] => one
    [9] => one
    [10] => one
    [11] => one
    [12] => one
    [13] => two
    [14] => one
)
Array
(
    [0] => one
    [1] => one
    [2] => one
    [3] => one
    [4] => one
    [5] => one
    [6] => one
    [7] => one
    [8] => one
    [9] => one
    [10] => one
    [11] => one
    [12] => one
    [13] => two
    [14] => two
)
Array
(
    [0] => one
    [1] => one
    [2] => one
    [3] => one
    [4] => one
    [5] => one
    [6] => one
    [7] => one
    [8] => one
    [9] => one
    [10] => one
    [11] => one
    [12] => one
    [13] => two
    [14] => three
)
Array
(
    [0] => one
    [1] => one
    [2] => one
    [3] => one
    [4] => one
    [5] => one
    [6] => one
    [7] => one
    [8] => one
    [9] => one
    [10] => one
    [11] => one
    [12] => one
    [13] => two
    [14] => four
)
Array
(
    [0] => one
    [1] => one
    [2] => one
    [3] => one
    [4] => one
    [5] => one
    [6] => one
    [7] => one
    [8] => one
    [9] => one
    [10] => one
    [11] => one
    [12] => one
    [13] => two
    [14] => five
)


мне 10% от сэкономленных
Сомневаюсь, что заказчика волнует экономия :) Скорее скорость решения задачи.. Сам на пиво скину, если его не заинтересует предложение уменьшить количество ВПС ;)
 

WMix

герр M:)ller
Партнер клуба
Тут нет значений массива после 10 значения
я свою поправил (следи за $k)
PHP:
function get($nr, $k){
  $arr = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen'];
  return array_map(function($n) use ($arr){
    return $arr[base_convert($n, count($arr), 10)];
  }, str_split(substr(str_pad( base_convert($nr, 10, count($arr)), $k, '0', STR_PAD_LEFT), $k * -1)));
}
for($x = 0; $x < 15; $x++){
    print_r(get($x, 15));
}
 
Последнее редактирование:

bubblegumoff

Новичок
я свою поправил (следи за $k)
PHP:
function get($nr, $k){
  $arr = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen'];
  return array_map(function($n) use ($arr){
    return $arr[base_convert($n, count($arr), 10)];
  }, str_split(substr(str_pad( base_convert($nr, 10, count($arr)), $k, '0', STR_PAD_LEFT), $k * -1)));
}
for($x = 0; $x < 15; $x++){
    print_r(get($x, 15));
}
Большое спасибо! С меня благодарочка по сдаче проекта и решении уменьшения количества впс ;)
 
Последнее редактирование:

bubblegumoff

Новичок
я свою поправил (следи за $k)
PHP:
function get($nr, $k){
  $arr = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen'];
  return array_map(function($n) use ($arr){
    return $arr[base_convert($n, count($arr), 10)];
  }, str_split(substr(str_pad( base_convert($nr, 10, count($arr)), $k, '0', STR_PAD_LEFT), $k * -1)));
}
for($x = 0; $x < 15; $x++){
    print_r(get($x, 15));
}
Снова в затруднительном положении.. А если в массиве больше 36 значений? В моём их больше тысячи.. Как быть?
 

WMix

герр M:)ller
Партнер клуба
написать свою base_convert, при этом можно сильно сократить функцию

PHP:
function bc($nr, $base){
   $out = [];
   while($nr > 0){
    $out[] = $nr%$base;
    $nr = intval($nr/$base);
   }
   return array_reverse($out);
}
print_r(bc(2439,16));
//Array
//(
//    [0] => 9
//    [1] => 8
//    [2] => 7
//)
98716 = 243910
, возможно bc_math придется использовать, возможно и его не хватит..
но тыж программист, ты сможешь
 

whirlwind

TDD infected, paranoid
По моему вы не туда полезли. Тут миллион способов как написать туповлоб

Код:
    @Test
    public void testX() {
       
        class Node {
            String root;
            List<String> words;
           
            Node(String root, List<String> words) {
                this.root = root;
                this.words = new ArrayList<>(words);
                this.words.remove(root);
            }
           
            Node(String root, String[] words) {
                this(root, Arrays.asList(words));
            }
           
            List<String> getClauses() {
                List<String> result = new ArrayList<>();
                if ( words.size() == 0 ) {
                    result.add(root);
                } else {
                    for ( String word : words ) {
                        Node n = new Node(word, words);
                        for ( String child : n.getClauses()  ) {
                            result.add(root + " " + child);
                        }
                    }
                }
                return result;
            }
           
        }
       
        String words[] = { "one", "two", "three", "four" };
        int count = 0;
        for ( String w : words ) {
            for ( String clause : new Node(w, words).getClauses() ) {
                System.out.println(clause);
                count ++;
            }
        }
        System.out.println("Total clauses: " + count);
       
    }
Код:
one two three four
one two four three
one three two four
one three four two
one four two three
one four three two
two one three four
two one four three
two three one four
two three four one
two four one three
two four three one
three one two four
three one four two
three two one four
three two four one
three four one two
three four two one
four one two three
four one three two
four two one three
four two three one
four three one two
four three two one
Total clauses: 24
ЗЫ. пыха нет под рукой
 
Сверху