spamsink: (Default)
[personal profile] spamsink
Старая, но хорошая. Для интервью, пожалуй, сложновасто, а как головоломка сгодится.

Дан целый массив, про который известно, что его элементы имеют значения в диапазоне от 0 до 7 включительно и весь он представляет одно большое восьмеричное число (концеватость по вкусу). Написать программу, которая переводит это число в десятичный вид (с той же концеватостью), используя O(1) дополнительной памяти.

Date: 2008-01-11 12:53 am (UTC)
From: [identity profile] gmz.livejournal.com
Уточнение: новое число должно быть в том же самом массиве?

Date: 2008-01-11 07:07 am (UTC)
From: [identity profile] avs313.livejournal.com
Считаем с большого конца по стандартной схеме (взяли первую цифру, умножили на 8, добавили очередную, и так пока цифры не закончатся). Т.к. 10 > 8, то освободившихся за ненадобностью элементов массива как раз хватит для хранения десятичного вида.

Date: 2008-01-11 07:14 am (UTC)
From: [identity profile] avs313.livejournal.com
И что? Или квадратичный алгоритм не подходит?
Все промежуточные результаты (а не только конечный), естественно, храним в освободившейся части массива, а не в инте каком-нибудь.

Date: 2008-01-11 02:58 pm (UTC)
From: [identity profile] ivan-ghandhi.livejournal.com
Easy. Но странно, как одни и те же идеи болтаются в воздухе; я то же самое обдумывал с утра (вчера).

Date: 2008-01-11 05:59 pm (UTC)
From: [identity profile] avs313.livejournal.com
ну код так код
кстати, про 5 строчек интересно, у меня сильно больше получилось

#include "stdio.h"

int main()
{
const int N = 10;
const int BASE1 = 8;
const int BASE2 = 10;
int arr[N];
int i;
for (i = 0; i < N; i++) arr[i] = 1;
arr[7] = 2;
for (i = 1; i < N; i++)
{
int v = arr[i]; arr[i] = 0;
for (int j = 0; j <= i; j++)
{
v += arr[j] * BASE1;
arr[j] = v % BASE2;
v /= BASE2;
}
}
return 0;
}

как тест забито (8^10 - 1) / (8 - 1) + 8^2 = (1 111 111 211)_8 = 153391753_10

Date: 2008-01-11 06:01 pm (UTC)
From: [identity profile] avs313.livejournal.com
да, забыл написать - начальные данные в big endian, результат - в little

Date: 2008-01-11 06:38 pm (UTC)
From: [identity profile] avs313.livejournal.com
тоже мне проблема
for (i = 0; i < (N / 2); ++i) swap(a[i], a[N - 1 - i]);
и все
перед return само собой

Date: 2008-01-11 06:45 pm (UTC)
From: [identity profile] avs313.livejournal.com
для меня это будет уже утро
жду :)

Квадратичное время

Date: 2008-01-11 07:42 pm (UTC)
From: [identity profile] ygam.livejournal.com
o2d [] = []
o2d (ol:oh) = decplus ol (mul8dec (o2d oh))

Re: Квадратичное время

Date: 2008-01-11 07:43 pm (UTC)
From: [identity profile] ygam.livejournal.com
Ой, не работает: стек линейный.

Re: Квадратичное время

Date: 2008-01-11 07:44 pm (UTC)
From: [identity profile] ygam.livejournal.com
Работает: нам стек не нужен.

Сейчас напишу код.

Date: 2008-01-11 08:02 pm (UTC)
From: [identity profile] ygam.livejournal.com
// Given an integer represented as an array of base-10 digits, multiply it by 8
// and add another number.
// The integer to multiply begins with digit 1; the number to add is at digit 0;
// the result begins with digit 0.
void mul8decshiftadd (unsigned char digits[], int n)
{
    unsigned char carry = digits[0];
    digits[0] = 0;
    for (int i=1;  i<n;  i++)
    {
        digits[i-1] += (8*digits[i])%10;
        digits[i] = (8*digits[i])/10;
    }
    for (int i=0;  i<n;  i++)
    {
        unsigned char nextCarry = (carry+digits[i])/10;
        digits[i] = (carry+digits[i])%10;
        carry = nextCarry;
    }
}

// Given an integer represented as an array of base-8 digits, transform it to base 10.
void octal2decimal (unsigned char digits[], int n)
{
    for (int m=n-1;  m>=0;  m--)
    {
        mul8decshiftadd (digits+m, n-m);
    }
}
Edited Date: 2008-01-11 08:02 pm (UTC)

Date: 2008-01-11 08:54 pm (UTC)
From: [identity profile] skavish.livejournal.com
так будет немного покороче, хотя должен признать что тут немного больше используется памяти :)


  void mul8decshiftadd(unsigned char digits[], int n) {
    int carry = digits[0];
    for (int i = 1; i < n; i++) {
      int sum = carry + 8 * digits[i];
      digits[i - 1] = sum % 10;
      carry = sum / 10;
      digits[i] = carry % 10;
    }
  }

Profile

spamsink: (Default)
spamsink

February 2026

S M T W T F S
12345 67
8 91011 121314
15161718 192021
22 2324 25262728

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Mar. 12th, 2026 08:54 am
Powered by Dreamwidth Studios