LINUX.ORG.RU

Говорили что Перл старый, ни на что не способный язык. Проверим?(часть 2)

 , ,


4

3

Задание на сейчас. найти максимальное вхождение одного слова в другое в СЛОВАРЕ - смотри ниже!!!

Перл - со словарём не справился;

Для C++ . - У меня перебирает весь словарь за 17 секунд;

Для JS - Около минуты. Говорили что Перл старый, ни на что не способный язык. Проверим?(часть 2) (комментарий);

Всё. Пока ничего другого, полностью рабочего нет.

Не нужно писать решение для единичных слов. Нужно - решение для словаря.

Возьмём список русских существительных, например отсюда: https://github.com/Harrix/Russian-Nouns/releases/download/v2.0/russian_nouns_v2.0.zip

Нужно найти максимальное вхождение одного слова в другое. Полные вхождения слов - не допускаются - это вроде было ясно и понятно всем. — Это задание. Это!!!


Самое простое и наглядное решение в составлении слов это:

/(\w+) \1/

Так-как даже я уже ничего не могу найти в первой части:

Говорили что Перл старый, ни на что не способный язык. Проверим?

Предлагаю собрать сюда наиболее значимые решения из 1 части.

Итак:

В начале, мы просто делали из

шлакоблок + окунь = шлакоблокунь

На разных языках. Там есть решения. Затем все стали зачем то уменьшать количество строк и символов - победил Перл - но это вообще не интересно.

Теперь, самое главное:

Говорили что Перл старый, ни на что не способный язык. Проверим?

Здесь все согласились что Перл хороший и годный язык, но С++ всё равно быстрее. В связи с этим, было предложено:

Говорили что Перл старый, ни на что не способный язык. Проверим?


Возьмём список русских существительных, например отсюда: https://github.com/Harrix/Russian-Nouns/releases/download/v2.0/russian_nouns_v2.0.zip На основе этого списка создадим новый, со всеми новыми сочетаниями, где перекрываются не менее 3 букв. Тут даже секундомером можно замерять. У меня на моем стареньком ноуте ушло несколько минут и сгенерировалось почти 40 Мбайт из одного. У Вас есть код на Перле и C++. Можете сравнить время. Так как здесь тоже работа со строками, то у Перла есть шанс.

Но потом договорились до изменения задания:

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

Единственное что мне приходит в голову - найти максимальное вхождение одного слова в другое. —!!! Это и стало основным и новым заданием. !!!—


Эти все задачи были решены для Перл и С++

Для Перл. 3 варианта решения. Но ни одно не берёт весь словарь:

#!/usr/bin/perl

use utf8;
use open qw(:std :utf8); 

$t = time();

$| = 1;
open D, 'russian_nouns.txt';

for(0..3000) {
  $vv=<D>;
  $vv =~ s/\s+$//;
  @d = (@d, $vv);
  }

close D;
@d2 = @d;


for $v (@d){
    ++$ii; if (++$j>99){
    $t2 = time()-$t;
    print $ii." прошло $t2 секунд. $sov1 $str\n"; $j=0;}

  for $v2 (@d2) {&resh3 ()}
  
M1:  
  }
  
sub resh3 {
  
  $lv = length $v;
  $lv2 = length $v2;

  if($lv>$lv2) {
  
    for($i=$lv2; $i>1; $i--) {
      $c = substr ($v, -$i,);
      $c2 = substr ($v2, 0, $i);
      if (($c eq $c2) and ($c ne $v2) and ($c ne $v)){
          $sov = length $c;
          if ($sov>$sov1){$sov1=$sov; $str="$c = $v-$v2"}
          }
        
  
      }

  
  }
  else {
    
        for($i=$lv; $i>1; $i--) {
      $c = substr ($v2, -$i,);
      $c2 = substr ($v, 0, $i);
      if (($c eq $c2) and ($c ne $v2) and ($c ne $v)){
          $sov = length $c;
          if ($sov>$sov1){$sov1=$sov; $str="$c = $v-$v2"}
          }
        
  
      }
    
    
    
    }
  
  
}
  

sub resh1 {  
    $r=''; $l='';
    for(split(//,$v2)){
      $r .= $_;
      if ($v =~ /$r$/) {$l=$r}  
      }
    #print "$v-$l-$v2\n" if length $l>4 and $v ne $l;
    
    if ($l and ($l ne $v2) and ($l ne $v)){
    $sov = length $l;
    if ($sov>$sov1){$sov1=$sov; $str="$l - $v-$v2"}
}
}


sub resh2 {
  
    if($v ne $v2) {
    $_ = "$v $v2";
    /([^ ]*?)([^ ]*) \2/;
    
    if ($2 and ($2 ne $v2) and ($2 ne $v)){
    $sov = length $2;
    if ($sov>$sov1){$sov1=$sov; $str="$2 - $_"}

}
  }}
  

Для C++ . У меня перебирает весь словарь за 17 секунд.:

#include <iostream>
#include <fstream>
#include <ctime>
#include <string>
#include <vector>
using namespace std;

void check_combine(string &res, size_t &len, const string &s1, const string &s2)
{
    len = 0;
    for(auto &ch: s1)
    {
        if(len == s2.size())
        {
            break;
        }
        if(ch == s2.at(len))
        {
            len += 1;
        }
        else
        {
            len = 0;
        }
    }
    if(!len)
    {
        res = "";
    }
    else
    {
        string s3  {s2};
        s3.erase(0, len);
        res = s1;
        res += s3;
    }
}

void getlines(vector<string> &lines, fstream & f)
{
    string str;
    while(getline(f, str))
    {
        lines.push_back(str);
    }
}

int main()
{
    fstream inFile;
    inFile.open ("russian_nouns.txt", std::fstream::in);
    vector<string> lines;
    getlines(lines, inFile);
    size_t maxLen  {0};
    size_t rusMaxLen  {0};
    string maxRes  {""};
    time_t startTime = time(nullptr);
    size_t counter  {0};
    for(auto &s1: lines)
    {
        for(auto &s2: lines)
        {
            counter += 1;
            if(s1 == s2)
            {
                continue;
            }
            if(s1.size() < maxLen)
            {
                continue;
            }
            if(s2.size() < maxLen)
            {
                continue;
            }
            size_t len  {0};
            string res;
            check_combine(res, len, s1, s2);
            if(res == s1)
            {
                continue;
            }
            if(res == s2)
            {
                continue;
            }
            if(len > maxLen)
            {
                maxLen = len;
                rusMaxLen = maxLen / 2;
                time_t delta = time(nullptr) - startTime;
                string deltaStr  {s2};
                deltaStr.erase(len);
                maxRes = deltaStr + " - " + s1 + '-' + s2;
                cout << counter << "\t прошло: " << delta << " секунд, длина: ";
                cout << rusMaxLen << ", " << maxRes << '\n';
            }
        }
    }
    cout << "\n\nРезультат: " << rusMaxLen << ", " << maxRes << '\n';
    time_t delta = time(nullptr) - startTime;
    cout << "Полное время переборов: " << delta;
    inFile.close();
    return 0;
}


Ниже - не решения текущей задачи! Не решения. Ниже - просто выборка всех решений, на всех языках с прежней темы.

Блин. Как же сложно с людьми с недостаточным образованием. Я вот уже 6 раз написал - и всё равно будут писать про Шлокоблококунь.

php:

➜ php i.php "папа + папаха"
папаха%                                                                                                                                                                   ➜ php i.php "шлакоблок + окунь"
шлакоблокунь%                                                                                                                                                              
➜ cat i.php
<?php
for ($i = 1; $i <= mb_strlen(trim(explode('+', $argv[1])[0])) && $i <= mb_strlen(trim(explode('+',$argv[1])[1])); $i++)
    if (mb_substr(trim(explode('+', $argv[1])[0]), mb_strlen(trim(explode('+',$argv[1])[0])) - $i) === mb_substr(trim(explode('+',$argv[1])[1]), 0, $i)) 
        $j = $i;
echo (isset($j)) ?  trim(explode('+',$argv[1])[0]). mb_substr(trim(explode('+',$argv[1])[1]), $j) : 'error';

Говорили что Перл старый, ни на что не способный язык. Проверим? (комментарий)



Последнее исправление: sudopacman (всего исправлений: 25)

Ответ на: комментарий от kompospec

Я ремонтировал телевизоры и мне нужны были генераторы полос которые я брал с Z80 - который пропал в неизвестном направлении. Кстати. Где он? Вы не знаете? Вроде сейчас - денег стоит. Или нет?

kompospec
() автор топика
Последнее исправление: kompospec (всего исправлений: 1)
Ответ на: комментарий от anonymous

Машинный код как язык программирования См. также: Язык ассемблера

Машинный код можно рассматривать как примитивный язык программирования или как самый низкий уровень представления

https://ru.wikipedia.org/wiki/%D0%9C%D0%B0%D1%88%D0%B8%D0%BD%D0%BD%D1%8B%D0%B9_%D0%BA%D0%BE%D0%B4

kompospec
() автор топика
Ответ на: комментарий от kompospec

«Машинный язык»

Я кодил на нём: C3 00 80 - что то вроде такого

«Машинный язык», да, в кавычках.

anonymous
()
Ответ на: комментарий от kompospec

Машинный код можно рассматривать как примитивный язык программирования или как самый низкий уровень представления

А можно и не рассматривать.

anonymous
()

Шлакоблокуньская программа на яве перебирает словарик за 16-18 секунд и генерит 589759 шлакоблокунeй (это в параллели на моём i7-6700, пришлось отказаться от явовских строк при проверках, могу ещё заоптимизировать, если надо…

anonymous
()
Ответ на: комментарий от anonymous

Шлакоблокуньская программа на яве перебирает словарик за 16-18 секунд и генерит 589759 шлакоблокунeй (это в параллели на моём i7-6700, пришлось отказаться от явовских строк при проверках, могу ещё заоптимизировать, если надо…

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

anonymous
()
Ответ на: комментарий от anonymous

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

Потому как нестандартными - например из Перла сделать С++ - я написал такую прогу, а потом компиляция. - Это вроде как не по Феншую.

kompospec
() автор топика
Ответ на: комментарий от kompospec

Единственный вариант - решить шлакоблокуня на асме; любому кто будет возмущаться что это не Перл говорить про тяжелое детство с дырами в полу

demensdeum
()

Есть такая утилитка — perlcc. Генерирует исходник на C, который можно потом собрать с помощью компилятора. К сожалению, существует не для всех версий perl…

Это не Пёрл, а Си будет.

anonymous
()
Ответ на: комментарий от kompospec

C3 00 80

Ооо, это же jmp на i8080/КР580ВМ80А, скорее всего, на z80 тоже. До сих пор ведь помню (а вот код той же команды на 8086 и следующих уже не помню и незачем…).

Верните мой 1992-й!

hobbit ★★★★★
()
Ответ на: комментарий от anonymous

Давай исходники

Ок, выложу эту простыню куда-нибудь

И оптимизируй.

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

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

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

anonymous
()
Ответ на: комментарий от anonymous

даже явного параллелизма не видят

Ну за кого-то, кстати, нода параллелит и JIT-компилирует. Если перепейсать на QuickJS, результат будет вдесятеро хуже.

import {loadFile} from 'std';

function combine(nouns) {
  var nl = nouns.length, i, j, k,
      wa, wb, dl, wal, wbl,
      maxa, maxb, maxl = 0
  for(i=0;i<nl;i++) {
    wa = nouns[i]
    wal = wa.length
    if(wal > maxl + 2) {
      for(k=0;k<nl;k++) {
        if(i!=k) {
          wb = nouns[k]
          wbl = wb.length
          if(wbl > maxl + 2) {
            for(j=1;j<wal&&!wb.startsWith(wa.slice(j));j++);
            dl = wal - j
            if(dl > maxl && dl < wbl && dl < wal) {
              maxl = dl
              maxa = wa
              maxb = wb
            } 
          }
        }
      }
    }
  }
  return [maxl, maxa, maxb]
}

var nouns = loadFile(scriptArgs[1], 'utf-8').split(/\s+/)

console.log('Total words:', nouns.length)
var time = Date.now()
var res = combine(nouns)
var timeEnd = Date.now()
console.log('Combination time:', (timeEnd - time)+'ms')
console.log('Max intersection:', res[0])
console.log('Word 1:', res[1])
console.log('Word 2:', res[2])
$ qjs shlak-qjs.js russian_nouns.txt 
Total words: 51301
Combination time: 20553ms
Max intersection: 13
Word 1: воспроизводитель
Word 2: производительность

Вот тут уже можно подумать, как распараллелить. Воркеры в QuickJS вроде как-то костыльновато, но поддерживаются.

anonymous
()
Ответ на: комментарий от anonymous

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

P.S. не знал, что нода научилась многопоточность, да ещё и сама параллелить

anonymous
()
Ответ на: комментарий от anonymous

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

А внутренний цикл продолжает проходить даже после определения maxl, т.к. не факт, что в этом цикле это пересечение точно максимальным окажется. А вот следующий внутренний цикл уже будет учитывать новое значение maxl.

anonymous
()
Ответ на: комментарий от anonymous

если у них длина всё равно не подойдёт для максимального пересечения

максимального пересечения надо между парой слов искать говно+овновед = говновед второе пересечение меньше букв, но больше слово говновновед

а ты вообще, какое-то левое отсечение сделал.

Нафига сохранять все комбинации?

Автор просил и в эталонной реализации на плюсах он так и делает?

anonymous
()
Ответ на: комментарий от anonymous

Хотя смотрю, что нет, посыпаю голову пеплом, действительно, теперь задача имеет ещё меньше смысла, боюсь, что так вообще будет быстро, только так называемый «максимальный шлакоблокунь» может меняться от запуска к запуску. Потом перепишем

anonymous
()
Ответ на: комментарий от anonymous

короче, переделал, если кому-то ещё интересно, пока в районе 2.5 секунд трудится, «шлакоблокунь» такой же получился: «воспроизводительность»

anonymous
()
Ответ на: комментарий от anonymous

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

anonymous
()
Ответ на: комментарий от anonymous
found: 14, electro[encephalograph]y, after 29.833021375s, using 4 cores
anonymous
()

Растрата человеческих ресурсов.

anonymous
()
Ответ на: комментарий от anonymous

У меня вот в новой вариации, сортирующей сначала список по длине

Дельное замечание, добавил сортировку, новый словарик грузит и сортирует за 0.2 секунды, за 33 секунды находит electroencyphalography

правда теперь замедлилось со старым словарём: 3 секунды, и тоже первым находит товаропроизводительность

anonymous
()
Ответ на: комментарий от anonymous

правда теперь замедлилось со старым словарём: 3 секунды, и тоже первым находит товаропроизводительность

А где «шлакаоблокоокунь»?

anonymous
()
Ответ на: комментарий от anonymous

А где «шлакаоблокоокунь»?

До него не доходит, слова из которых он состоит меньше найденого ранее пересечения

anonymous
()

Мне кажется Swift еще не было в треде, может тут с ошибкой, но простой тест-кейс проходит, пусть компостец посмотрит

import Foundation

let lhs = "Говно"
let rhs = "ноздри"

print("\(lhs.prefix(lhs.count - lhs.enumerated().map{lhs.suffix(lhs.count-$0.offset)}.first{rhs.hasPrefix($0)}!.count))\(rhs)")

Проверить тут можно
https://swiftfiddle.com/3cieiz7sq5dfnn4jfvul6qpn3q

demensdeum
()

Кому интересно, на явке код выкладываю: https://dpaste.org/1HGz

Можете смеяться с монстра!

anonymous
()

на старых Пердах стоял компилятор

Это пять. Можно закрывать тред. ТС признал превосходство. См. удалённые.

anonymous
()
Ответ на: комментарий от anonymous

Вот. О чём и речь. Все эти реализации под маленький словарь. На большем словаре подход другой быстрей.

anonymous
()

Кстати, прочитал тут в одном месте (место не называется по политическим причинам), что всякие Си плохо компилируются и оптимизируются если целевая архитектура сильно отличается от привычной amd64. Так что нужно тестировать всё это на экзотическом железе. На MIPS каком-нибудь. Или RISC-V. Иначе всё это вилами по воде.

anonymous
()
Ответ на: комментарий от anonymous

Пердл там тож тормозной будет значицс

anonymous
()

ТС, все же, какая практическая необходимость в получении

РЫБАУТЮГ? ...
anonymous
()
Ответ на: комментарий от kompospec

Деньги. - Это написано через каждые 4 страницы в каждой из тем. Повторять в 5 раз я не буду

Это в постах было, а того в каких задач возникла в нем необходимость, вроде не было …

anonymous
()
Ответ на: комментарий от kompospec

Деньги. - Это написано через каждые 4 страницы в каждой из тем. Повторять в 5 раз я не буду

А зачем жирножопу деньги, если есть жировая прослойка?

anonymous
()
Ответ на: комментарий от kompospec

Было. и ссылки на исходное задание - были

Ссылка там на «зарегистрируйтесь, чтобы прочитать». Т.е. нету ссылки. Марать себя регистрацией будет только падшая душонка.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.