Задача та же. Восемь ферзей.

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

Каждая цифра — отдельный столбец.

Значение — номер строки.

#!/bin/bash
# 8 ферзей

awk 'BEGIN{
  i=8^8
  while(i--){
    c=sprintf("%08o",i)
    j=8
    while(index(c,--j)){}
    if(j<0){
      j=8
      while(j--){q[j]=substr(c,j+1,1)}
      b=1
      for(m=0;m<7 && b;m++){
        for(j=m+1;j<8;j++){
          a=q[m]-q[j];sub(/-/,"",a)
          if(a==(j-m)){b=0;break}
        }
      }
      if(b){print c}
    }
  }
}'

while(index(c,--j)){} — чисел всего 8 (0–7). Если index=0 (нет цифры j в числе c из 8 цифр), значит каких-то цифр две.

Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос
Обратите внимание: тело цикла пустое! Если цикл прошёл полностью — дублей нет. Вау.

Алгоритм пермутаций без повторений методом перебора (проверка на горизонталь).

while(j--){q[j]=substr(c,j+1,1)} — преобразовали число c в массив цифр q[].

Дальше аналогично предыдущей программе, кроме sub(/-/,"",a) — ещё один аналог модуля.

Просто отбрасываем -. Как конструкция по скорости — не знаю, не проверял.

Программа отработала примерно за 41 с.

Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос
Какой-то код маленький получился и работает быстрее. Но главное — результаты совпадают.

Кто там хотел изучать Bash?

Слабо реализовать на чистом Bash?

Интересно было бы и время выполнения сравнить.